Страницы

Поиск по вопросам

воскресенье, 30 сентября 2018 г.

Что такое Null Pointer Exception и как его исправить?

Что из себя представляет исключение Null Pointer Exception (java.lang.NullPointerException) и почему оно может происходить?
Какие методы и средства использовать, чтобы определить причину возникновения этого исключения, приводящего к преждевременному прекращению работы приложения?
Перевод вопроса «What is a Null Pointer Exception, and how do I fix it?» @Ziggy


Ответ

Когда вы объявляете переменную ссылочного типа, на самом деле вы создаете ссылку на объект данного типа. Рассмотрим следующий код для объявления переменной типа int:
int x; x = 10;
В этом примере переменная x имеет тип int и Java инициализирует её как 0. Когда вы присвоите переменной значение 10 (вторая строка), это значение сохранится в ячейке памяти, на которую ссылается x
Но когда вы объявляете ссылочный тип, процесс выглядит иначе. Посмотрим на следующий код:
Integer num; num = new Integer(10);
В первой строке объявлена переменная num, ее тип не относится к встроенному, следовательно, значением является ссылка (тип этой переменной, Integer, является ссылочным типом). Поскольку вы еще не указали, на что собираетесь ссылаться, Java присвоит переменной значение Null, подразумевая «Я ни на что не ссылаюсь».
Во второй строке, ключевое слово new используется для создания объекта типа Integer. Этот объект имеет адрес в памяти, который присваивается переменной num. Теперь, с помощью переменной num вы можете обратиться к объекту используя оператора разыменования .
Исключение, о котором вы говорите в вопросе, возникает, если вы объявили переменную, но не создали объект, то есть если вы попытаетесь разыменовать num до того, как создали объект, вы получите NullPointerException. В самом простом случае, компилятор обнаружит проблему и сообщит, что
num may not have been initialized
Что говорит: «возможно, переменная num не инициализирована».
Иногда исключение вызвано именно тем, что объект действительно не был создан. К примеру, у вас может быть следующая функция:
public void doSomething(Integer num){ // Работаем с num }
В этом случае создание объекта (переменная num) лежит на вызывающем коде, то есть вы предполагаете, что он был создан ранее – до вызова метода doSomething. К сожалению, следующий вызов метода вполне возможен:
doSomething(null);
В этом случае значение переменной num будет null. Лучшим способом избежать данного исключения будет проверка на равенство нулю. Как результат, функция doSomething должна быть переписана следующим образом:
public void doSomething(Integer num){ if (num != null) { // Работаем с num } }
Как альтернативный вариант предыдущему примеру вы можете сообщить вызывающему коду, что метод был вызван с неверными параметрами, например, с помощью IllegalArgumentException
public void doSomething(Integer num){ if (num == null) throw new IllegalArgumentException("Num не должен быть null"); // Работаем с num }
Также, обратите внимание на вопрос «Что такое stack trace и как с его помощью находить ошибки при разработке приложений?».
Перевод ответа «What is a Null Pointer Exception, and how do I fix it?» @Vincent Ramdhanie

Как правильно выбрать название для юнит-теста?

Это был обычный будний день, я начал писать очередной обычный тест, но при написании названия теста что-то пошло не так:
testCustomerRedirectUrlAfterSelectLastTransactionProcessShouldContainsUrlToConfirmRecurringProfilePageWhenTransactionTypeIsCreateRecurringProfile
Примерно на середине я начал осознавать что происходит что-то не то, но я не остановился и дописал название теста до конца. Коллеги не оценили такое длиннющее название теста, но мне оно нравится. Сейчас используется что-то вроде testCorrectChangeCustomerRedirectUrl, а детали того что тест тестирует скрыты внутри теста.
Я не могу понять это лвлап, либо я устал под вечер.
Вопрос: Каковы критерии выбора хорошего названия теста?
UPD: Пожалуйста, приведите названия тестов из ваших проектов.


Ответ

Название для тестов не надо выбирать красивое. Название нужно выбирать функциональное и по возможности короткое -- чтобы по минимальному количеству символов было понятно, что и под какими условиями он тестирует, а также чтобы можно было отличить конкретный тест от тысяч других.
Распространенные шаблоны наименования такие:
TestClass_TestMethod_ConditionAndExpectedResult (для юнит-тестов) TestMethod_Condition_ExpectedResult (для юнит-тестов) ConditionAndExpectedResult (для интеграционных тестов, которые тестируют целые блоки функциональности через некоторую входную точку)
При этом если у вас в частях Condition/ExpectedResult слишком много разных условий/результатов, объединенных по "И", то вам нужно пересмотреть либо главную цель теста (что он тестирует), либо главное условие, которое отличает тест от других, и разбить его на несколько отдельных тестов.

Я ратую прежде всего за то, что название должно быть информативным, но при этом настолько коротким, насколько возможно. Тут точно так же как и со всем остальным кодом -- чем меньше кода, тем меньше времени нужно чтобы его понять, тем проще разбираться с ним. Судя по вашему названию, это не простой маленький юнит-тест, а что-то побольше, поэтому совсем коротким названием тут не обойтись. В вашем случае, если тест класс у вам уже для Customer, я бы ограничился названием SelectLastTransactionProcess_CreateRecurringProfile_RedirectUrlShouldContainConfirmation. В вашем названии много повторений слов: transaction, url, recurring profile и т.д. Они избыточны.
Между длиной и информативностью названия безусловно должен быть баланс. Достаточно, чтоб названия были понятны разработчикам внутри проекта, которые уже обладают контекстом и способны понять, о чем этот тест. И если для этого нужно длину названия сделать не 30 символов, а 40, сделайте. Но не нужно стремиться к тому, чтоб названия были понятны каждому встречному, попутно рассказывая обо всей системе, поскольку это приводит к таким вот километровым названиям, в которых сложно разобраться. Посмотрите на свой обычный код, посмотрите на названия методов. Вы ведь не описываете в названии метода каждую его деталь, каждую строчку? Вы описываете нечто главное, а остальное спрятано внутри. Точно так же и с тестовыми методами.

Кто-нибудь может ещё рассказать что делать с названиями интеграционных тестов, > где 100500 различных условий? К примеру биллинг, принимает на вход 5-10 видов прайс-листов и в зависимости от их комбинаций и комбинаций их параметров (тоже примерно 5-10) должен выдавать различные суммы на выход. Контейнер отправляемый в биллинг занимает ~30 строчек. Если в стиле поста называть тесты то это будет testPayoutDebtorToGateOntopGateTransactionAmountGateToCreditorFlatPayinDebtorTo‌​GateOntopTotalTransactionAmountGateToCreditorOntopTransactionAmount, причем не с полным контекстом. Нужно рассчитать итоговую сумму исходя из того что прайс-листы могли быть настроены следующим образом: Тип комиссии прайс-листа типа основной сделки - inside/total, комиссия 0.1% + 0.5руб cверху, расчет вести от оборота. Второй комиссионный прайс-лист ontop/gate.. ещё в таком же стиле раз 10 и пара неявных зависимостей прайс-листов друг от друга.
Я бы сказал, что вам нужен параметрический тест. Это такой тест, который одним кодом тестирует разные наборы данных. Например, в терминах тестового фреймворка xUnit параметрический тест метода Calculator.Add() может выглядеть так:
[Theory] // это параметрический тест [InlineDate(1, 2, 3)] // наборы данных, т.е. параметры теста [InlineDate(0, 1, 1)] [InlineDate(-1, 1, 0)] public void Calculator_Add_ShouldReturnCorrectResult(int a, int b, int expectedResult) { var result = Calculator.Add(a, b); Assert.AreEqual(result, expectedResult); }
С параметрическими тестами вам не нужно перечислять все условия в названиях -- название содержит только суть теста, что именно тестируется, конкретный кейс. В вашем случае это что-то вроде РасчетИтоговойСтоимости_ПоОсновнойИДополнительнойСделке (на английский сами переведете, вам область понятнее). А выглядеть ваш тестовый метод может так (при этом в xUnit тестовые данные можно подставлять из свойства и даже из отдельного объекта):
[Theory] [PropertyData("PriceData")] // тестовые данные находятся в отдельном свойстве public void РасчетИтоговойСтоимости_ПоОсновнойИДополнительнойСделке( ComissionType mainComissionType, Comission mainComission, CalculationType mainCalculationType, ComissionType auxComissionType, Comission auxComission, CalculationType auxCalculationType, double expectedPrice) { // код теста }
public static IEnumerable PriceData { get { // данные можете захардкодить, а можете прочитать из файла return new[] { new object[] { // основная сделка ComissionType.InsideTotal, new Comission(0.1, 0.5), CalculationType.ОтОборота, // дополнительная сделка ComissionType.OnTopGate, new Comission(0.42, 0.99), CalculationType.ОтБалды, // результат 100500 }, // и так далее для других пар }; } }
Я думаю во многих тестовых фреймворка есть возможность создания параметрических тестов. Способ задания параметров может отличаться, но суть останется та же: данные выносятся в секцию с данным, в названии теста остается только название кейса.
Дополнительную информацию о параметрических тестах можной найти в блоге Сергея Теплякова.

Книги и учебные ресурсы по C#

Вопросы о литературе по различным языкам программирования возникают очень часто. Здесь мы попробуем собрать лучшие ответы и рекомендации насчёт литературы и других учебных ресурсов по языку C#, платформе и популярным библиотекам.
Не забывайте, однако, что никакая теория не заменит опыта программирования! Читайте, пробуйте, тренируйтесь. Спрашивайте, если непонятно. Попробуйте запрограммировать свой проект, это лучший путь.

Данный перечень входит в поддерживаемый сообществом Сборник учебных ресурсов по программированию


Ответ

Литература по языку C#
Книги для новичков: а о чём это вообще?
Head First C#, Jennifer Greene, Andrew Stellman (русский перевод: Изучаем C#, Д. Грин, Э. Стиллмен). Содержит упражнения. Рекомендуется многими как хорошая книга для новичков. C# 6.0 and the .NET 4.6 Framework (7th Edition), Andrew Troelsen, Philip Japikse (русский перевод предыдущего издания: Язык программирования C# 5.0 и платформа .NET 4.5, Эндрю Троелсен). Хорошая популярная книга, многие начинали с неё. C# 4.0: полное руководство, Герберт Шилдт. Несмотря на неоднозначное отношение к автору, книга пользуется популярностью. C# 2010. Ускоренный курс для профессионалов, Нэш Трей
Книги среднего уровня: если hello world не проблема
CLR via C#. Программирование на платформе Microsoft .NET Framework 4.5 на языке C#, Джеффри Рихтер. Неувядающая классика. Хотите знать, что и как происходит на самом деле? Это книжка для вас. Не самое живое изложение, местами скучновата, зато максимум подробностей из первых рук. Предупреждение: Русский перевод от «Питер» ужасен: вас ждут выброшенные абзацы, опечатки и ляпы, меняющие смысл текста на противоположный. По возможности, читайте английский оригинал. C# 7.0 in a Nutshell: The Definitive Reference, Joseph Albahari, Ben Albahari (русский перевод предыдущего издания: C# 6.0. Справочник. Полное описание языка, Джозеф Албахари, Бен Албахари). Отличная книга, затрагивает многие аспекты, расставляет по местам ваши знания о предмете. Сводит разрозненные отрывочные знания в общую понятную картину, объясняет, какими средствами нужно пользоваться, а для чего есть уже более хорошие подходы. Есть online-глава о многопоточности, почитайте!
русский перевод главы о многопоточности: часть 1, часть 2, часть 3, часть 4, часть 5.1, часть 5.2 Essential C# 6.0, Mark Michaelis в сооавторстве с Эриком Липпертом. Хорошая книга для программистов, желающих овладеть C#. Знания других языков, перед чтением, приветствуются. От Эрика Липперта в книге представлены продвинутые советы, которые встречаются на протяжении всей книги. Effective C# и More Effective C#, Bill Wagner. О том, как надо и как не надо программировать на C#. Разбираются отдельные аспекты программирования, способствует углублению понимания языка. Programming C# 5.0: Building Windows 8, Web, and Desktop Applications for the .NET 4.5 Framework, Ian Griffiths (русский перевод : Программирование на C# 5.0, Иэн Гриффитс). Очень детальная, подробная книга, в которой найдутся ответы на продвинутые вопросы.
Книги для специалистов: внутренние механизмы и пыльные углы
C# in Depth, Jon Skeet, Third Edition (русский перевод: C# для профессионалов. Тонкости программирования, Джон Скит, Третье издание). Имя автора говорит само за себя. Джон один из лучших людей, которые умеют доходчиво объяснять сложные вещи. C# 5 Unleashed, Барт де Смет. Фундаментальная книга. Debugging Microsoft .NET 2.0 Applications, John Robbins (русский перевод: Отладка приложений для Microsoft .NET, Джон Роббинс). Основы промышленной отладки: WinDbg/SOS, дампы памяти и решение проблем в приложениях (почти) без Visual Studio. Under the Hood of .NET Memory Management, Chris Farrell, Nick Harrison. Полное описание всех тонкостей управления памятью в платформе .NET. Книга доступна бесплатно на английском. Expert .NET 2.0 IL Assembler, Serge Lidin. В книге представлена информация о почти всех тонкостях низкоуровневого программирования на .NET, а именно на языке IL. В книге описаны детали .NET Framework 2.0, по этому на данный момент какие-то аспекты могут быть неактуальны. Оптимизация приложений на платформе .NET с использованием языка C#, Саша Голдштейн, Дима Зурбалев, Идо Флатов (Переводчик: Александр Киселев). В книге рассматривается моменты .NET с точки зрения производительности. Рассказывается об способах замеров и шаблонах оптимизации. Также там рассматриваются вопросы, связанные с GC и небезопасным кодом. (Саша Голдштейн — признанный эксперт в этой области.)
Дополнительные ресурсы:
Официальная спецификация C# 5 и текущий черновик официальной спецификации C# 6 Framework Design Guidelines. Руководства и соглашения по проектированию многократно используемого кода. Является выдержкой из одноимённой книги, Krzysztof Cwalina, Brad Abrams. Книга переведена на русский под названием Инфраструктура программных проектов, Кржиштоф Цвалина, Брэд Абрамс.

Литература по асинхронному программированию и многопоточности
Concurrent Programming on Windows, Joe Duffy. Профессиональное использование многопоточности в инфраструктуре .NET от одного из лучших мировых специалистов по многопоточности. В книги описаны тонкости использования как stream'oв так и thread'ов. Раскрыто, как и когда использовать Concurrent-, Parallel- и Asynchronous-модели. Примеры в книге присутствуют от достаточно низкоуровневых (с использованием системных потоков через WinAPI) до высокоуровневых Task'ов и PLINQ. Книга написана под .NET Framework 4.0, поэтому работа с ключевыми словами async/await в книгу не вошла. Concurrency in C# Cookbook, Stephen Cleary. (Русского перевода пока нет.) Очень толковое разъяснение современных паттернов использования многопоточности, особое внимание уделено использованию конструкции async/await. Обсуждается решение типичных проблем, решаемых асинхронным кодом. Отдельно описывается работа с Reactive Extensions и TPL Dataflow.

Литература по WPF
Pro WPF 4.5 in C#: Windows Presentation Foundation in .NET 4.5, Matthew MacDonald (русский перевод: WPF: Windows Presentation Foundation в .NET 4.5 с примерами на C# 5.0 для профессионалов, Мэтью Макдональд). Разбор XAML'а, лаконичные, но полезные примеры. Пристальное, но не навязчивое внимание к деталям. Windows Presentation Foundation Unleashed, Adam Nathan. Наверное, лучшая книга для новичка. Applications = Code + Markup: A Guide to the Microsoft Windows Presentation Foundation, Чарльз Петцольд. Фундаментальная книга великолепного специалиста. Написана довольно тяжело, много листингов, плотный поток информации

Литература по ASP.NET
Pro ASP.NET MVC 5, Adam Freeman (русский перевод: ASP.NET MVC 5 с примерами на C# 5.0 для профессионалов, Адам Фримен). Поэтапное написание веб-приложения с рассмотрением большинства важных аспектов разработки приложения: паттерн MVC, юнит-тестирование, инверсия зависимостей и т. п. Pro ASP.NET 4.5 in C#, Adam Freeman (русский перевод: ASP.NET 4.5 с примерами на C# 5.0 для профессионалов, Адам Фримен). Professional ASP.NET MVC 5, Jon Galloway, Phil Haack, Brad Wilson, K. Scott Allen Programming ASP.NET MVC 4: Developing Real-World Web Applications with ASP.NET MVC, Jess Chadwick, Todd Snyder, Hrusikesh Panda (русский перевод: ASP.NET MVC 4. Разработка реальных веб-приложений с помощью ASP.NET MVC, Джесс Чедвик, Хришикеш Панда, Тодд Снайдер). ASP.NET MVC Framework, Гайдар Магдануров, Владимир Юнев Pro ASP.NET MVC 2 Framework, Steven Sanderson (русский перевод: ASP.NET MVC Framework с примерами на C# для профессионалов, Стивен Сандерсон)
Дополнительные ресурсы:
Get Started with ASP.NET от Microsoft Видеокурсы на intuit.ru: Разработка веб-приложений на ASP.NET, Разработка веб-приложений с использованием ASP.NET MVC Framework Документация по ASP.NET Core и ASP.NET Core MVC

Литература по LINQ
Pro LINQ: Language Integrated Query in C# 2010, Joseph Rattz, Adam Freeman (русский перевод: LINQ. Язык интегрированных запросов в C# 2010 для профессионалов, Адам Фримен, Джозеф С. Раттц). Учебно-справочное пособие, в котором понятно и подробно описаны возможности языка LINQ. Хороша для старта. LINQ Pocket Reference, Joseph Albahari, Ben Albahari (русский перевод: LINQ. Карманный справочник, Джозеф Албахари, Бен Албахари). Хороший справочник по всему, что относится к LINQ. Рассмотрены новые конструкции C# для поддержки LINQ. Много примеров. C# in Depth, Jon Skeet (русский перевод: C#. Программирование для профессионалов, Джон Скит). Немалая часть книги посвящена тому, как работает LINQ.

Литература по принципам, шаблонам и методикам разработки
Руководство Microsoft по проектированию архитектуры приложений, 2-е издание Системный труд, в котором вы постоянно будете узнавать отсылки к тем или иным книгам, паттернам и архитектурны приёмам. Внедрение зависимостей в .NET, Марк Симан. Несложно написанная книга про управление зависимостями в приложениях. Принципы, паттерны и методики гибкой разработки на языке C#, Роберт С. Мартин, Мика Мартин

Литература по Windows Workflow Foundation
Essential Windows Workflow Foundation, Dharma Shukla, Bob Schmidt (русский перевод: Основы Windows Workflow Foundation, Дхарма Шукла, Боб Шмидт). Для тех, кого заинтересовала 26 глава («Введение в Windows Workflow Foundation») из книги Эндрю Троелсена Язык программирования C# 5.0 и платформа .NET 4.5 Pro WF 4.5, Bayer White (русской версии нет). Более углубленный взгляд на WF.

Литература по XML
XML.NET, Джо Грей, Динар Дальви, Бипин Джоши, Фредрик Нормен, Фрэнсис Нортон, Энди Ольсен, Дж. Майкл Палермо IV, Даршан Сингх, Джон Слэйтер, Кевин Уильямс (Переводчик: И. Штерев). В книги содержится всё про применение XML в .NET за исключением LINQ. Старовата уже, но зато там есть объяснение, как внедрить свои функции на C# в XSLT.

Литература по ADO.NET
Основы ADO.NET, Боб Бошемин (Переводчики: О.А. Лещинский, А.В. Журавлев, Н.Н. Селина)

Литература по .NET Remoting / WCF
Microsoft .NET Remoting, Скотт Маклин, Джеймс Нафтел, Ким Уильямс Создание служб WCF, Джувел Леве (Переводчики: Е. Матвеев, А. Пасечник) Основы windows communication foundation, Стив Резник, Ричард Крейн, Крис Боуэн

Литература по безопасности
Криптография и безопасность в технологии .NET, Питер Торстейнсон, Гнана Ганеш (Переводчик: В. Хорев). Книга дает представление .NET разработчику о реализации и применении криптографии, цифровой подписи, аутентификации, авторизации и доступа к коду (CAS). В ней описывается, что такое симметричное и асимметричное шифрование, что представляют собой цифровые подписи и как их использовать в .NET приложениях. Microsoft ASP.NET. Обеспечение безопасности, Доминик Байер. Не смотря на то, что в названии указано ASP.NET в книге рассматриваются технологии безопасности под Windows, применимые из .NET для всех типов приложений. Это аутентификация, авторизация, олицетворение и Membership.
Книги и учебные материалы по Entity Framework
К сожалению, до сих пор нет книг на русском языке, поэтому на русском языке можно порекомендовать только следующие материалы:
Руководство по Entity Framework Руководство по Entity Framework Core Работа с Entity Framework 6

Как устроить ловушку для хакера, или достойно отбивать атаки?

Ребята выручайте. Меня взломали и в наглую соединились со мной, требуя денег. Я новичок в этом деле и думаю, что пока научусь, то офис скорее снимет меня с работы.
Недавно сайт стал зависать, похоже было на DDOS атаку. Забанил его по IP, но бесполезно. Я устал бегать за IP и банить их, да и в принципе это не выход. Просто когда с хакером переписывался, он сделал ряд проколов, сказав, что может сломать даже мою базу данных. Я когда проверял базу во время перегрузок, то на нее никаких нагрузок не было, в основном на сервер. Меняю всякий раз все возможные пароли, но хакер беспрепятственно обходит их.
И так, шаря, да выискивая слабые места, наткнулся на то, что мой сервер выдает страницы не только по index.php, но и по abc.php, xyz.php. Не знаю, блин, но носом чую, что гад припрятал какой-то файл и обращается к нему. Где и идут тормоза, заполняя канал на 100%. Базу удалить, в принципе, можно будет изнутри этого файла (DELTE FROM tbl_name).
Как можно найти этот файл, или как можно понять какой-то необычный вход на сервер? У меня Symfony 1.4 PHP фреймворк. Сайт 5 летней давности. Писать его заново? (не вариант, по крайней мере не сейчас). Что я пропустил на уровне хранения лишнего файла? Или не в ту сторону копаю?
Я слышал от друзей что в 90 % за этим стоят конкуренты. И в обратку хакнув его, чаще всего ддос прекращается. Но мысль навредить кому-то из за своей слабости чего-то не вдохновляет.
Попросил хакера дать время, чтоб якобы уболтать начальство расскошелиться.


Ответ

В принципе не важно вас взломали,или пытаются взломать,ведь рано или поздно мы сталкнёмся с этой угрозой. Всe действия описанные ниже помогут узнать о ваших слабых и уязвимых местах, помогут исправить допущенные ошибки, помогут вам грамотно защищаться и в дальнейшем эффективно бороться с этим злом. Научимся методике и технологиям устраивании ловушек для злоумышленников (Honeypot - горшочек с медом).
Приведу действия первой необходимости:
Если вас уже взломали:
Меняем логины и пароли серверов (Linux, MySQL, .....). Убеждаемся что у нас как минимум две группы пользователей с разными привилегиями.Допустим web и root, где web эта привилегия стоит для всех пользователей с ограниченными возможностями(Запрет на закачку файлов кроме image type). Как правильно дать привилегии ? Читаем Как Повысить безопасность и удобство использования Вашего сервера и заложить прочную основу для последующих действий. Если GIT не показывает необыкновенные изменения,то может быть стоит заглянуть в те директории которые вне него.Чаще всего это те директории куда загружаются изображения или иные файлы которые позволяем пользователям загружать. find . -type f -name '*.php' | xargs grep -l "eval *(str_rot13 *(base64_decode *(" --color Эта команда найдет php файлы содержащие eval(str_rot13(base64_decode( (Также можно искать и в базе данных SELCT col_nam FROM tbl_name WHERE col_name LIKE '%eval(str_rot13(base64_decode(%'). Синтаксис grep очень прост и вы можете изменить его под свои нужды.
На уровне PHP:
**Ограничивать использование опасных php функций в php.ini ** (disable_functions = "show_source, system, shell_exec, exec, eval" ).Можно закрыть mail() функцию.и зафиксировать обращение к SMTP через сокетное соединение на 25 порт. Тут обращу внимание на функцию eval. Если каким то образом в вашем коде припрятан PHP код то его исполнение через eval не произойдет.Этот список можно дополнять или убавлять по необходимости.Все отключили любые PHP скрипты которые были написаны надеюсь не нами. Межсайтовая подделка запроса (CSRF (англ. Сross Site Request Forgery )): Много популярных фреймворков имеют полноценную защиту от него в том числе и ваш.Распространённым способом защиты является механизм, когда с каждой сессией пользователя ассоциируется дополнительный секретный ключ,и при отправки запроса в месте с параметрами и отправляется сгенерированный токен.А потом сравниваются сгенерированный токен и токен пришедший с запросом,если совпадают то этот запрос неподделанный. Эффективен для выполнения POST, PUT, DELETE, STORE-запросов. Межсайтовый скриптинг XSS (англ. Cross-Site Scripting). Выводить текст сохраненной не вами на страницу так как его вводили.Тут есть нюансы. Если пользователь сохраняет текст (К примеру оставляет комментарий, или делает поиск по сайту) у вас в базе или еще где нибудь, то надо учесть что если нужен только текст тогда до сохранения очистить его от нежелательных тeгов(Для PHP strip_tags — Удаляет HTML и PHP-теги из строки). Если все таки нужно пропускать теги то сделать какие нибудь предварительные валидации.Или вводить их маркируя по принципу stackoverflow textarea.Мы же публикуя вопрос или ответ не можем же вводить любой тег.Просто забыл как называется такие типы маркировки текста :) Всегда тщательно проверяйте файлы которые загружаются на сервер через форму или каким нибудь способом.Проверяйте их расширения и содержимое.Часто загрузка файлов без обеспечения надлежащего контроля безопасности приводит к образованию уязвимостей, которые, как показывает практика, стали настоящей проблемой в веб-приложениях на PHP.Чтобы удостовериться, что это действительно изображение не используйте getimagesize() для проверки того, что файл является файлом с изображением. Для этих целей используйте расширение Fileinfo. Стоит добавить, что желательно сделать приведение файла к конкретному формату, например png. При приведении метаданные картинки потеряются, обеспечив практически гарантируемую безопастность.Наличие в загрузке файлов с расширением типа .php нужно проверять вообще в начале работы сайта, и если они есть сразу же их отбрасывать.
На уровне .htaccess
Ограничивать точки входа на сайте
Например в фреймворках в основном доступ идет через index.php.Или других вами известных файлах (admin.php,back.php, ...). Всегда можно отследить обращение к другому файлу, и всегда можно логировать информацию об обращениях к подозрительному файлу в отдельном журнале. проверьте .htaccess файлы на подозрительные изменения.auto_append_file и auto_prepend_file включают другие PHP файлы в начале или в конце всех PHP скриптов, злоумышленники могут использовать их для включения своего кода. find . -type f -name '\.htaccess' | xargs grep -i auto_prepend_file; Следующая команда ищет во всех подкаталогах файлы .htacсess, которые содержат 'http'. Результатом поиска будет список всех правил перенаправлений, в которых могут быть и вредоносные правила find . -type f -name '\.htaccess' | xargs grep -i http; . Во все каталоги, доступные для записи добавляем файл .htaccess со следующим содержимым:
php_flag engine 0
AddType "text/html" .php .cgi .pl .fcgi .fpl .phtml .shtml .php2 .php3 .php4 .php5 .asp .jsp
Этим самым мы отключаем PHP в данном каталоге и заставляем все скрипты отображаться как HTML. Это можно сделать просто на всякий случай. Лишним уж точно не будет.
Или запрет на исполнение:
Order Allow,Deny Deny from all
На уровне баз данных,частностью MySQL:
Всегда пользуйтесь Подготовленными запросами и хранимыми процедурами: Большинство баз данных поддерживают концепцию подготовленных запросов. Что это такое? Это можно описать, как некий вид скомпилированного шаблона SQL запроса, который будет запускаться приложением и настраиваться с помощью входных параметров. У подготовленных запросов есть два главных преимущества:
Запрос необходимо однажды подготовить и затем его можно запускать столько раз, сколько нужно, причем как с теми же, так и с отличающимися параметрами. Параметры подготовленного запроса не требуется экранировать кавычками; драйвер это делает автоматически. Если в приложении используются исключительно подготовленные запросы, разработчик может быть уверен, что никаких SQL инъекций случиться не может (однако, если другие части текста запроса записаны с неэкранированными символами, SQL-инъекции все же возможны; здесь речь идет именно о параметрах). Защищайтесь от SQL-инъекции
Прямое внедрение вредоносных инструкций в SQL-запросы - это методика, в которой взломщик создает или изменяет текущие SQL-запросы для отображения скрытых данных, их изменения или даже выполнения опасных команд операционной системы на сервере базы данных. Атака выполняется на базе приложения, строящего SQL-запросы из пользовательского ввода и статических параметров.
На уровне системы Linux ...
Лучше этих сервисов, которые реально защищают от DDOS, я пока не знаю.Пользуюсь ими.Пока что отбивают :).Это Cloudflare ,и Incapsula
Как устроить ловушку для хакера (Honeypot - горшочек с медом):
Не занимайтесь этим если у вас нет достаточных знаний и квалификации, хакер может победить вас в вашей же ловушке.
Honeypot (горшочек с медом) давно широко используется в мире компьютерной безопасности.Это ресурс, задача которого отдаться хакеру, цель которого принять тест, атаку и быть взломанным.
Это может быть эмулятор другой системы или приложения, некая "темница с засадой", или просто стандартная система. Как бы вы не построили свой горшочек, главная его задача — подвергнутся нападению и рассказать вам в подробностях об этом.
Quick and Simple PHP Honey Pot Spam Prevention Simple PHP HoneyPot Tutorial Изучить инструменты, тактику и мотивы, связанные с компьютерными и сетевыми атаками, и поделиться извлеченными уроками.
Естественно все в этом посте перечислить невозможно.Но если попытаться реализовать все что в этом посте перечислено,то можно научиться защищаться и не хило.По каждому из пунктов можно всегда задать вопрос или поискать больше информации для более детальной и правильной ее реализации.
Полезные материалы :
Веб-сервисы для проверки сайтов на вирусы https://habrahabr.ru/post/303956/ Методы борьбы с DDoS-атаками https://habrahabr.ru/post/129181/ 5 советов по борьбе с DDOS-атаками http://www.securitylab.ru/analytics/442099.php Устоять любой ценой: методы борьбы с DoS/DDoS-атаками https://xakep.ru/2009/10/14/49752/ 5 программ для анализа безопасности Вашего сайта https://seo-zona.ru/5-programm-dlya-analiza-bezopasnosti-vashego-sajta-2015-03-31.html Как понять что ваш сайт был взломан https://www.siteguarding.com/ru/kak-poniat-chto-vash-sait-byl-vzloman
Бесплатный онлайн-сканеры вирусов:
Веб-сканер QUTTERA https://quttera.com/ Веб-сканер ReScan.pro https://rescan.pro/ VirusTotal https://www.virustotal.com/ru/ Веб-сканер Sucuri https://sitecheck.sucuri.net/ Онлайн—сканеры Dr.Web https://vms.drweb.ru/online/
Вооружайтесь знаниями. Будьте бдительней.
Удачи :)

В чем польза yield?

Пример на С#.
Возвращаем коллекцию с помощью yield
public static class Foo { public static IEnumerable Test() { var rand = new Random().Next(1, 3); if (rand == 1) yield return 1;
if (rand == 2) yield return 2;
yield return 3; yield return "foo"; yield return true; } }
Пример 2. Возвращаем коллекцию с помощью обычного листа.
public static class Foo1 { public static IEnumerable Test() { var list = new List(); var rand = new Random().Next(1, 3); if (rand == 1) list.Add(1);
if (rand == 2) list.Add(2);
list.Add(3); list.Add("foo"); list.Add(true);
return list; } }
Результат равнозначен, вопрос - зачем тогда вообще нужен yield, если можно обойтись таким кодом? Или yield используется там, где код с new List() по каким-то причинам невозможен?


Ответ

Ну, отличие на самом деле кардинальное.
Дело в том, что в первом случае у вас ленивое, а во втором — энергичное вычисление ответа. Это значит, что элементы выходной последовательности в энергичном случае вычисляются все и сразу, а в ленивом случае — только когда запрошены и только те, что запрошены.
Давайте посмотрим, где с практической стороны есть разница.
Для случая ленивого вычисления вся последовательность не присутствует полностью в памяти. Это значит, что при поэлементной обработке у нас не выделяется память, и сохраняется cache locality:
IEnumerable GenerateHugeSequenceLazy() { for (int i = 0; i < 1000000; i++) yield return 13 * i; }
IEnumerable GenerateHugeSequenceEager() { var result = new List(); for (int i = 0; i < 1000000; i++) result.Add(13 * i); return result; }
Вычисляем функцию на всей последовательности, сравниваем расход памяти:
var seqLazy = GenerateHugeSequenceLazy(); // вычисляем максимум вручную var max = 0; foreach (var v in seqLazy) if (v > max) max = v;
var memLazy = GC.GetTotalMemory(forceFullCollection: false);
var seqEager = GenerateHugeSequenceEager(); // вычисляем максимум вручную max = 0; foreach (var v in seqEager) if (v > max) max = v;
var memEager = GC.GetTotalMemory(forceFullCollection: false);
Console.WriteLine($"Memory footprint lazy: {memLazy}, eager: {memEager}");
Результат:
Memory footprint lazy: 29868, eager: 6323088

Затем, у нас довольно большие различия в смысле операций. Ленивые вычисления происходят в момент, когда они нужны. А значит, состояние аргументов будет взято на момент реального перечисления. Вот пример:
IEnumerable DoubleEager(IEnumerable seq) { var result = new List(); foreach (var e in seq) result.Add(e * 2); return result; }
IEnumerable DoubleLazy(IEnumerable seq) { foreach (var e in seq) yield return e * 2; }
Смотрим на отличия:
var seq = new List() { 1 }; var eagerlyDoubled = DoubleEager(seq); var lazilyDoubled = DoubleLazy(seq);
Console.WriteLine("Eager: " + string.Join(" ", eagerlyDoubled)); Console.WriteLine("Lazy : " + string.Join(" ", lazilyDoubled)); // выводит оба раза 2, покамест различий нет
seq.Add(2); // модифицируем *исходную* последовательность
Console.WriteLine("Eager: " + string.Join(" ", eagerlyDoubled)); // 2 Console.WriteLine("Lazy : " + string.Join(" ", lazilyDoubled)); // 2 4
Поскольку ленивое вычисление происходит при перечислении, мы видим, что при изменении последовательности ленивая версия подхватывает изменения.

Другой пример. Посмотрим, что будет, если мы не вычисляем всю последовательность. Вычислим одну и ту же последовательность энергично и лениво:
IEnumerable Eager10() { Console.WriteLine("Eager"); int counter = 0; try { var result = new List(); for (int i = 0; i < 10; i++) { Console.WriteLine($"Adding: {i}"); counter++; result.Add(i); } return result; } finally { Console.WriteLine($"Eagerly computed: {counter}"); } }
IEnumerable Lazy10() { Console.WriteLine("Lazy"); int counter = 0; try { for (int i = 0; i < 10; i++) { Console.WriteLine($"Adding: {i}"); counter++; yield return i; } } finally { Console.WriteLine($"Lazily computed: {counter}"); } }
Берём только 2 элемента из результата:
foreach (var e in Eager10().Take(2)) Console.WriteLine($"Obtained: {e}");
foreach (var e in Lazy10().Take(2)) Console.WriteLine($"Obtained: {e}");
foreach (var e in Lazy10()) { Console.WriteLine($"Obtained: {e}"); if (e == 1) break; }
Получаем такой вывод на консоль:
Eager Adding: 0 Adding: 1 Adding: 2 Adding: 3 Adding: 4 Adding: 5 Adding: 6 Adding: 7 Adding: 8 Adding: 9 Eagerly computed: 10 Obtained: 0 Obtained: 1 Lazy Adding: 0 Obtained: 0 Adding: 1 Obtained: 1 Lazily computed: 2 Lazy Adding: 0 Obtained: 0 Adding: 1 Obtained: 1 Lazily computed: 2
Видите разницу? Ленивый вариант прогнал цикл всего два раза, и не вычислял «хвост» последовательности.

Ещё одна разница между случаями — когда сообщаются ошибки. В случае энергичного вычисления они сообщаются сразу. В случае ленивого — лишь при перечислении результата. Пример:
IEnumerable CheckEagerly(int value) { if (value == 0) throw new ArgumentException("value cannot be 0"); return new List { value }; }
IEnumerable CheckLazily(int value) { if (value == 0) throw new ArgumentException("value cannot be 0"); yield return value; }
Применяем try/catch:
Console.WriteLine("Eager:"); IEnumerable seqEager = null; try { seqEager = CheckEagerly(0); } catch (ArgumentException) { Console.WriteLine("Exception caught"); }
if (seqEager != null) foreach (var e in seqEager) Console.WriteLine(e);
Console.WriteLine("Lazy:"); IEnumerable seqLazy = null; try { seqLazy = CheckLazily(0); } catch (ArgumentException) { Console.WriteLine("Exception caught"); }
if (seqLazy != null) foreach (var e in seqLazy) Console.WriteLine(e);
Получаем результат:
Eager: Exception caught Lazy:
Unhandled Exception: System.ArgumentException: value cannot be 0 at Program.d__3.MoveNext() in ...\Program.cs:line 59 at Program.Run() in ...\Program.cs:line 45 at Program.Main(String[] args) in ...\Program.cs:line 13

Ещё один случай различия — зависимость от внешних данных в процессе вычисления. Следующий код пытается влиять на вычисления, изменяя глобальное состояние. (Это не очень хороший код, не делайте так в реальных программах!)
bool evilMutableAllowCompute;
IEnumerable EagerGet5WithExternalDependency() { List result = new List(); for (int i = 0; i < 5; i++) { if (evilMutableAllowCompute) result.Add(i); } return result; }
IEnumerable LazyGet5WithExternalDependency() { for (int i = 0; i < 5; i++) { if (evilMutableAllowCompute) yield return i; } }
Используем:
Console.WriteLine("Eager:"); evilMutableAllowCompute = true; foreach (var e in EagerGet5WithExternalDependency()) { Console.WriteLine($"Obtained: {e}"); if (e > 0) evilMutableAllowCompute = false; }
Console.WriteLine("Lazy:"); evilMutableAllowCompute = true; foreach (var e in LazyGet5WithExternalDependency()) { Console.WriteLine($"Obtained: {e}"); if (e > 0) evilMutableAllowCompute = false; }
Результат:
Eager: Obtained: 0 Obtained: 1 Obtained: 2 Obtained: 3 Obtained: 4 Lazy: Obtained: 0 Obtained: 1
Мы видим, что изменение глобальных данных даже после формальной отработки ленивой функции может влиять на вычисления.
(Это ещё один аргумент в пользу того, что функциональное программирование и мутабельное состояние плохо сочетаются.)

Многопоточное vs асинхронное программирование

Хотелось бы узнать разницу между этими подходами. Разве асинхронное программирование не подразумевает из себя уже многопоточность, ведь Task где-то там по любому выполняется в отдельном потоке ?
В каких случаях нужно прибегать к многопоточному, а в каких к асинхронному программированию ?
И еще ко всему этому есть параллельное программирование, которая тоже вносит путаницу для меня. В чем её отличие ?


Ответ

Попробую собрать воедино все, что дали уже в комментариях.
Есть несколько разных понятий, связанных с областью параллельных вычислений.
Конкурентное исполнение (concurrency) Параллельное исполнение (parallel execution) Многопоточное исполнение (multithreading) Асинхронное исполнение (asynchrony)
Каждый из этих терминов строго определен и имеет четкое значение.
Конкурентность (concurrency)
Конкурентность (*) (concurrency) - это наиболее общий термин, который говорит, что одновременно выполняется более одной задачи. Например, вы можете одновременно смотреть телевизор и комментить фоточки в фейсбуке. Винда, даже 95-я могла (**) одновременно играть музыку и показывать фотки.
(*) К сожалению, вменяемого русскоязычного термина я не знаю. Википедия говорит, что concurrent computing - это параллельные вычисления, но как тогда будет parallel computing по русски?
(**) Да, вспоминается анекдот про Билла Гейтса и многозадачность винды, но, теоретически винда могла делать несколько дел одновременно. Хотя и не любых.
Конкурентное исполнение - это самый общий термин, который не говорит о том, каким образом эта конкурентность будет получена: путем приостановки некоторых вычислительных элементов и их переключение на другую задачу, путем действительно одновременного исполнения, путем делегации работы другим устройствам или еще как-то. Это не важно.
Конкурентное исполнение говорит о том, что за определенный промежуток времени будет решена более, чем одна задача. Точка.
Параллельное исполнение
Параллельное исполнение (parallel computing) подразумевает наличие более одного вычислительного устройства (например, процессора), которые будут одновременно выполнять несколько задач.
Параллельное исполнение - это строгое подмножество конкурентного исполнения. Это значит, что на компьютере с одним процессором параллельное программирование - невозможно;)
Многопоточность
Многопоточность - это один из способов реализации конкурентного исполнения путем выделения абстракции "рабочего потока" (worker thread).
Потоки "абстрагируют" от пользователя низкоуровневые детали и позволяют выполнять более чем одну работу "параллельно". Операционная система, среда исполнения или библиотека прячет подробности того, будет многопоточное исполнение конкурентным (когда потоков больше чем физических процессоров), или параллельным (когда число потоков меньше или равно числу процессоров и несколько задач физически выполняются одновременно).
Асинхронное исполнение
Асинхронность (asynchrony) подразумевает, что операция может быть выполнена кем-то на стороне: удаленным веб-узлом, сервером или другим устройством за пределами текущего вычислительного устройства.
Основное свойство таких операций в том, что начало такой операции требует значительно меньшего времени, чем основная работа. Что позволяет выполнять множество асинхронных операций одновременно даже на устройстве с небольшим числом вычислительных устройств.
CPU-bound и IO-Bound операции
Еще один важный момент, с точки зрения разработчика - разница между CPU-bound и IO-bound операциями. CPU-Bound операции нагружают вычислительные мощности текущего устройства, а IO-Bound позволяют выполнить задачу вне текущей железки.
Разница важна тем, что число одновременных операций зависит от того, к какой категории они относятся. Вполне нормально запустить параллельно сотни IO-Bound операций, и надеяться, что хватит ресурсов обработать все результаты. Запускать же параллельно слишком большое число CPU-bound операций (больше, чем число вычислительных устройств) бессмысленно.

Возвращаясь к исходному вопросу: нет смысла выполнять в 1000 потоков метод Calc, если он является CPU-Intensive (нагружает центральный процессор), поскольку это приведет к падению общей эффективности вычислений. ОС-ке придется переключать несколько доступных ядер для обслуживания сотен потоков. А этот процесс не является дешевым.
Самым простым и эффективным способом решения CPU-Intensive задачи, заключается в использовании идиомы Fork-Join: задачу (например, входные данные) нужно разбить на определенное число подзадач, которые можно выполнить параллельно. Каждая подзадача должна быть независимой и не обращаться к разделяемым переменным/памяти. Затем, нужно собрать промежуточные результаты и объединить их.
Именно на этом принципе основан PLINQ. О чем можно почитать тут: Джозеф Албахари. Параллельное программирование
Выглядит это очень интересно:
IEnumerable yourData = GetYourData(); var result = yourData.AsParallel() // начинаем обрабатывать параллельно .Select(d => ComputeMD5(d)) // Вычисляем параллельно .Where(md5 => IsValid(md5)) .ToArray(); // Возврвщаемся к синхронной модели
В этом случае, число потоков будет контролироваться библиотечным кодом в недрах CLR/TPL и метод ComputeMD5 будет вызван параллельно N-раз на компьютере с N-процессорами (ядрами).

Хороший стиль обработки ошибок

Правильная и хорошая обработка ошибок и их генерация — довольно важная часть в разработке ПО. Но как это делать правильно и красиво — советов мало, и они очень поверхностны. Объясните, пожалуйста, принципы хорошей обработки ошибок (желательно в Java) вместе с примерами.
UPD1:
Когда делать RuntimeException, а когда просто Exception? Единственен ли способ генерации ошибки оператором throw? В каких лучше случаях создать, допустим, MyException extends Exception, а затем MyOtherException extends MyException? Иными словами, как увидеть необходимость в иерархии ошибок? Когда делать примерно так:
public void f() throws MyException { //некоторый код ... if (....){ throw MyException(...); } } Какие еще есть способы генерации ошибок? Когда правильнее переносить ошибку на уровень функции (... f() throws ...)?


Ответ

Во-первых, как уже говорилось, используйте исключения. Создайте свою иерархию исключений и продумайте, какие из них сделать runtime, а какие нет. Никогда не используйте конструкции типа new Exception(...) или new RuntimeException. Вместо этого старайтесь создавать и кидать только адекватные ситуации исключения. Создание экземпляра Exception или RuntimeException — халтура и отписка вместо обработки ошибок.
Не забывайте проверять все параметры в конструкторах и, по возможности, в методах и своевременно кидать IllegalArgumentException. Пользуйтесь стандартными исключениями в соответствующих случаях. Используйте их по назначению и никогда не кидайте что попало.
Пользуйтесь try/catch/finally. Не забывайте уничтожать ресурсы.
Пользуйтесь логгерами, а не делайте e.printStackTrace. Никогда не делайте catch пустым, если только вы не уверены, что должны именно проигнорировать исключение.
При логгировании пользуйтесь по возможности полный метод log с уровнем логгирования, сообщением и исключением. Старайтесь в сообщении к логу описать, что именно упало и добавить какие-то сведения об условиях в блоке try. Это поможет выявить проблемы в боевых условиях. Старайтесь назначать адекватные уровни логгирования.
Настраивайте логгер. В некоторых случаях следует разделять логи для ошибок и варнингов. В противном случае сообщения об ошибках могут сротироваться и потеряться из-за менее важных сообщениях.
Подцепите что-то вроде аудита, если приложение серверное. Возможно стоит в особо фатальных случаях слать письмо админам.
Если это клиентское приложение на свинге, то можно отображать сообщение об ошибке с окне или в виде маленькой иконки в панели статуса.
UPD1
Когда делать RuntimeException, а когда просто Exception?
Это довольно сложный вопрос и трудно дать общие рекомендации. Но в общем случае следует руководствоваться фатальностью ошибки и её вероятности возникновения. Также следует учитывать возможное расстояние от места генерирования ошибки до места фактической обработки. Например, IOException нельзя просто никак не обработать и это верно. Если его не обработать, то могут застрять какие-то ресурсы. И обычно обработка такой ошибки находится сравнительно близко от места её возникновения. В то же время IllegalArgumentException можно не отлавливать... так как обычно это ошибки, связанные с неправильным использованием API, неверное конфигурацией или недостаточной валидацией данных от пользователя. И попытка ловить такие исключения всюду привела бы к краху: код стал бы просто нечитаем. Иными словами, требуется здравый смысл.
Единственен ли способ генерации ошибки оператором throw?
Нет, исключение не обязательно кидать. Например, в GWT (и не только) имеется интерфейс AsyncCallback, который имеет метод onError, принимающий исключение в качестве параметра. Соответствующий код не кидает исключение через throw, а просто вызывает callback-метод и передаёт туда исключение. А уж callback сам решит, что с этим исключением делать.
В каких лучше случаях создать, допустим, MyException extends Exception, а затем MyOtherException extends MyException? Иными словами, как увидеть необходимость в иерархии ошибок?
Очевидно в тех случаях, когда между исключениями могут быть какие-то «родственные» связи. Когда какие-то группы исключений имеют что-то общее.
Когда делать примерно так:
public void f() throws MyException { //некоторый код ... if (....){ throw MyException(...); } }
Всегда, когда if позволяет определить, что что-то пошло не по плану.
Какие еще есть способы генерации ошибок?
Собственно, assert, throwи просто вызов обработчика с параметром-исключением.
Когда правильнее переносить ошибку на уровень функции (... f() throws ...)?
Опять же лучший пример — IOException. Так следует делать всегда, когда есть ошибка, но вы точно знаете, что клиент (вызывающий ваш метод) может захотеть узнать об ошибке явно, а не по косвенным признакам. Так, например, если кто-то читает из сокета, то он хочет знать, что чтение невозможно и просто предвать операцию вместо того, чтобы каждый раз проверять, работает ли сокет или лепить бесконечные if-ы проверяя код ошибки после каждого метода read.
UPD
Да, пожалуй, по моему мнению, хорошим примером неправильного выбора между Exception и RuntimeException является InterruptedException. Было бы гораздо лучше, если бы он был Runtime. В результате либо всюду приходится его ловить и игнорировать, либо везде пробрасывать.. продумывая кейз, который никогда не произойдёт. И эти загромождения сильно портят код.