Страницы

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

среда, 31 октября 2018 г.

Как прописать PATH в Ubuntu?

Скачал texlive 15, в конце установщик попросил сделать это:
Добавьте /usr/local/texlive/2015/texmf-dist/doc/man в MANPATH Добавьте /usr/local/texlive/2015/texmf-dist/doc/info в INFOPATH И самое главное, добавьте /usr/local/texlive/2015/bin/i386-linux в ваш PATH для текущей и будущих сессий.
Как это сделать?


Ответ

Довольно простой способ прописать что-то в PATH -- это открыть файл .bashrc (или .zshrc, или файл для другой используемой оболочки), лежащий в домашнем каталоге (~/.bashrc), и дописать в конце:
# add texlive to PATH export PATH=$PATH:/usr/local/texlive/2015/bin/i386-linux export INFOPATH=$INFOPATH:/usr/local/texlive/2015/texmf-dist/doc/info export MANPATH=$MANPATH:/usr/local/texlive/2015/texmf-dist/doc/man
Для того, чтобы действия вступили в силу, можно либо перезапустить терминал, либо ввести
source ~/.bashrc

Пояснение:
Синтаксис
export VAR=$VAR:path
используется для добавления нового пути в переменную. Символ является символом разделения путей в linux. Если бы требовалось только создать новую переменную, а не добавлять значение к возможно имеющейся, синтаксис был бы проще:
export VAR=value

Исключения и ошибки в php. Что когда использовать и как?

Хочу разобраться как делать правильно.
Сейчас у меня в коде обработчик ошибок (ErrorHandler) обрабатывает как внутренние ошибки скрипта, так и исключения, которые я сам создаю. Выглядит этот так:
class ErrorHandler { public static function register() { ini_set('display_errors', 'on'); error_reporting(E_ALL); set_error_handler(get_class() . "::showError"); register_shutdown_function(get_class() . "::catch_fatal_error"); ob_start(); }
/** * @param int $errno * @param string $errstr * @param string $file * @param int $line * @param string $header */ public static function showError($errno, $errstr, $file, $line, $header = "HTTP/1.0 404 Not Found") {/*здесь отправляю ответ об ошибке*/}
public static function catch_fatal_error() { /*здесь отправляю ответ о критической ошибке при помощи все того же метода self::showError*/ } }
Весь код приложения заключен в блок try{} и исключение обрабатывается при помощи все того же метода:
try{ //Здесь весь код моего приложения //в нем встречаются такие выбросы ошибок: throw new \Exception("Сообщение об ошибке."); } catch(\Exception $e){ //обрабатывается исключение при помощи все того же метода класса ErrorHandler ErrorHandler::showError($e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine()); }
Вопросы:
Можно ли так делать? Какой наиболее приемлемый вариант работы с ошибками и исключениями, если мой неверный?
Вопрос возник потому, что мой знакомый, которого я считаю более продвинутым чем я, говорит, что так как у меня делать нельзя. Но я не могу понять почему. Что не так?
Некоторые важные моменты, которые я понял:
Когда возникает фатальная ошибка, то она автоматически попадает в буфер вывода. Это означает, что мы можем сразу его удалять и НЕ создавать предварительно вручную функцией ob_start();, если, конечно, хотим обрабатывать фатальные ошибки тоже. Что не рекомендуется делать. Директива ini_set('display_errors', 'on'); в моем коде лишняя, т.к. я сам решаю, что делать с ошибками и мне не нужно сообщать php, что ему делать с ними. Я уже сам решу. А остальным пусть занимаются базовые настройки сервера. Отправлять ответ пользователю внутри обработчика ошибок допустимо. Т.к. другие механизмы ответа, предусмотренные приложением, могут быть недоступны как раз из-за этих ошибок. Встроенный обработчик именно это делает - он прерывает в месте ошибки ход программы и отправляет ответ пользователю.


Ответ

В целом ваша механика отлова ошибок верная, потому мне не очень понятна критика вашего товарища. Было бы здорово взглянуть на его решение.
Теперь по существу. Собственно, класс обработчик ошибок:
class ErrorHandler { protected $format = '{{message}} {{class}}::{{method}} {{file}} on line {{line}}'; /** * @var HandlerInterface */ protected $displayHandler;
/** * @var integer the size of the reserved memory. A portion of memory is pre-allocated so that * when an out-of-memory issue occurs, the error handler is able to handle the error with * the help of this reserved memory. If you set this value to be 0, no memory will be reserved. * Defaults to 256KB. */ protected $memoryReserveSize = 262144; /** * @var string Used to reserve memory for fatal error handler. */ private $_memoryReserve;
/** * Register this error handler. */ public function register() { // Catch errors set_error_handler([$this, 'handleError']);
if ($this->memoryReserveSize > 0) { $this->_memoryReserve = str_repeat('x', $this->memoryReserveSize); } // Start buffer ob_start(); // Catch fatal errors register_shutdown_function([$this, 'handleShutdown']); }
/** * Unregisters this error handler by restoring the PHP error handlers. */ public function unregister() { restore_error_handler(); }
/** * Error handler. * * @param int $code * @param string $msg * @param string $file * @param int $line * @return bool * @throws \ErrorException */ public function handleError($code, $msg, $file, $line) { if (~error_reporting() & $code) { return false; }
switch ($code) { case E_USER_WARNING: case E_WARNING: $exception = new \ErrorException("[E_WARNING] {$msg}", Log::WARNING, $code, $file, $line); break; case E_USER_NOTICE: case E_NOTICE: case E_STRICT: $exception = new \ErrorException("[E_NOTICE] {$msg}", Log::NOTICE, $code, $file, $line); break; case E_RECOVERABLE_ERROR: $exception = new \ErrorException("[E_CATCHABLE] {$msg}", Log::ERROR, $code, $file, $line); break; default: $exception = new \ErrorException("[E_UNKNOWN] {$msg}", Log::CRITICAL, $code, $file, $line); }
throw $exception; }
/** * Fatal handler. * * @return void */ public function handleShutdown() { unset($this->_memoryReserve);
$error = error_get_last(); if ( isset($error['type']) && ($error['type'] == E_ERROR || $error['type'] == E_PARSE || $error['type'] == E_COMPILE_ERROR || $error['type'] == E_CORE_ERROR) ) {
$type = ""; switch ($error['type']) { case E_ERROR: $type = '[E_ERROR]'; break; case E_PARSE: $type = '[E_PARSE]'; break; case E_COMPILE_ERROR: $type = '[E_COMPILE_ERROR]'; break; case E_CORE_ERROR: $type = '[E_CORE_ERROR]'; break; } $exception = new \ErrorException("$type {$error['message']}", Log::CRITICAL, $error['type'], $error['file'], $error['line']); if (APP_LOG) { Log::log(Log::CRITICAL, $this->convertExceptionToString($exception)); } $this->display($exception); } else { if (ob_get_length() !== false) { // Display buffer, complete work buffer ob_end_flush(); } } }
/** * Sets a display handler. * @param HandlerInterface $handler */ public function setDisplayHandler(HandlerInterface $handler) { $this->displayHandler = $handler; }
/** * Sets a format message log. * @param string $format */ public function setFormat($format) { $this->format = $format; }
/** * Sets a size memory. * @param int $size */ public function setMemoryReserve($size) { $this->memoryReserveSize = $size; }
/** * @param \Exception $exception */ public function display(\Exception $exception) { // display Whoops if (APP_DEBUG === true) { if (!isset($this->displayHandler)) { $this->displayHandler = new PrettyPageHandler(); } $run = new Run(); $run->pushHandler($this->displayHandler); $run->handleException($exception); return; }
die('This site is temporarily unavailable. Please, visit the page later.'); }
/** * Converts an exception into a simple string. * * @param \Exception $exception the exception being converted * @return string the string representation of the exception. */ public function convertExceptionToString(\Exception $exception) { $trace = $exception->getTrace(); $placeholders = [ '{{class}}' => isset($trace[0]['class']) ? $trace[0]['class'] : '', '{{method}}' => isset($trace[0]['function']) ? $trace[0]['function'] : '', '{{message}}' => $exception->getMessage(), '{{file}}' => $exception->getFile(), '{{line}}' => $exception->getLine(), ];
return strtr($this->format, $placeholders); } }
Класс может быть и статическим (т.е. содержать статические методы и свойства). Не имеет значения.
За отображение исключений и ошибок в красивом интерфейсе отвечает вполне известная библиотека Whoops, а логирование производится с помощью Monolog (здесь представлен лёгенький wrapper над ней)
Существуют различные нюансы, к примеру, для отлова фатала связанного с переполнением памяти (Allowed memory size of...), необходимо зарезервировать некий объём. Опытным путём был рассчитан объём в 256KB. Об этом я узнал на одной из конференции от Александра samdark Макарова (евангелист и мэйнтейнер фреймворка yii). Собственно, в обработчике фреймворка подобный хак имеется. Если проанализировать код обработчика yii2, то можно заментить другие нюансы связанные, к примеру, с обработкой ошибок/исключений HHVM.
В единой точке входна в ваше приложение (index.php) указываем следующее:
defined('APP_DEBUG') or define('APP_DEBUG', true); defined('APP_LOG') or define('APP_LOG', true);
$errorHandler = new ErrorHandler; $errorHandler->register();
try {
// ... bootstrap вашего приложения
} catch (\Exception $e) { if (APP_LOG) { $msg = $errorHandler->convertExceptionToString($e); Log::log($e->getCode() ? : Log::CRITICAL, $msg); } $errorHandler->display($e); }
В самом приложение можно ловить локальные исключения и делать с ними всё что угодно. К примеру, ловить и тут же логировать:
try {
// ... некая локальная логика приложения
} catch (\Exception $e) { Log::log(Log::ERROR, (new ErrorHandler())->convertExceptionToString($e)); }
Так или иначе, любое выбрашенное исключение будет отловлено в index.php и в зависимости от заданных констант (APP_DEBUG и APP_LOG) представленно в красивом интерфейсе и добавлено в лог. Естественно на продакшене стоит обязательно отключить режим дебага.
По поводу обработчиков Whoops:
Зная в каком формате (content type) вам необходимо отдать данные пользователю, можно выбрать подходящий обработчик.
К примеру, проверка является ли запрос ajax-запросом
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') { $errorHandler->setDisplayHandler(new JsonResponseHandler()); }
Дебаг-информация будет представлена в виде json-а, что удобно для просмотра через консоль браузера.
В идеале необходимо иметь HTTP прослойку (классы Response/Request) и всё это детектить на уровне роутинга или фильтров/поведений контроллера - ContentNegotiator или что-то подобное.
P.S. Посмотрите видео холивара про оператор подавления ошибок @ с devconf. Очень занимательно.

UPDATE
Я лично в проектах стараюсь возвращать верные http-статусы. Вам никто не мешает выдать пользовотелю специально оформленную 404-страницу с аналогичным статусом.
if (headers_sent()) { // проверка: не отправлены ли уже заголовоки return; } $version = isset($_SERVER['SERVER_PROTOCOL']) && $_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.0' ? '1.0' : '1.1' $statusCode = 404; $statusText = 'Not Found';
header("HTTP/$version $statusCode $statusText");
Как я уже отмечал ранее, лучше всего использовать класс-прослойку Response над нативными функциями.
С роутингом этого добиться досточно просто:
$route = new Route(); $route->get('/items/{id:\d+}/', ['
amespace\ItemsController', 'actionOne']); $route->post('/items/', ['
amespace\ItemsController', 'actionCreate']); //... другие правила $route->any('*', ['
amespace\ItemsController', 'actionNotFound']); // т.е. если вышеприведенные правила не выполнились, то выполнится последнее правило.
Для ajax-запрос, достаточно в ответе указать заголовок без тела:
$route->any('*', function(Route $route) { $route->response->status404(); return $route->response; });
403 - если доступ к ресурсу (по какому-то URL-у) запрещен для неавторизованного пользователя или пользователя с иной ролью/правами, к примеру, не имеющего права администратора. Посмотрите RBAC. В yii подобный механизм реализован через поведения/фильтры к экшенам контроллера.
201 - ресурс успешно создан. К примеру, можно выдавать, когда зарегистрирован пользователь, создан комментарий или пост.
204 - запрос к БД завершился успешно, но данные по какой-то причине отсутствуют. К примеру, открылся новый раздел на сайте, но статьи для него ещё не написаны.
422 я использую, если не прошла валидация данных, к примеру формы. В данном случае, через $statusText (см. выше), можно дать пояснение: Validation failure
429 - классический rate limiter. Чаще всего применятеся для REST API. При достижении определённого лимита на количтво запросов выдавать данный статус.
302 - при редиректе. К примеру, если данные пришедшие от формы верны и запись в БД успешно произведена, то проивзодится редирект на стороннюю страницу, либо рефреш текущий страницы с данным статус.
500 - если вы могли заметить, то в ErrorHandler имеется die('This site is temporarily unavailable. Please, visit the page later.');. Вы можете вместо этой "пресной" записи выдать пользователю статичную страницу-заглушку предварительно указав http-статус 500.
die(file_get_contents('/path/to/stub.html'));
Для реализации своего RESTful API указание верныx http-методов, статусов, заголовков (почитайте про HATEOAS) является обязательных.
Полный список статусов
Таким образом, в режиме дебага у вас будет выводится Whoops со стек-трейсом, а на продакшене (боевом сервере) пользователю будет показана заглушка. Логировать или нет ошибки/исключения на ваше усмотрение. К примеру, во многих фреймворках по умолчанию производлится "информационное" логирование (level Log::INFO), т.е. каждое соединие с БД, успешность транзакций, авторизация пользователя и т.д., что хорошенько может так забить ваш накопитель на сервере. Необходимо повышать уровень логирования ошибок до Log::WARNING или Log::ERROR, а также использоватать штатные утилиты по ротации логов. К примеру, в Linux это logrotate
Коль я затронул тут множество тем, то позвольте прорекламировать мои open source библиотеки:
Rock Route - роутинг с гибкими правилами, группировкой (разделение правил на пространства/модули для, к примеру, ajax, backend/админка и т.д., как в laravel) и поддержкой REST. Алгоритм реализации облегчённых regexp-паттернов был взят из библиотеки FastRoute Никиты Попова (входит в core team PHP). Имеется подробная документация. Rock Response - форк yii2 response, который полностью отделён от фреймворка. Документации, к сожалению нет, но существует официальная документации yii. Правда, тоже пока короткая.
Как мы знаем yii2 является монолитным фреймворком. Rock Request - аналогичный форк, но с моей библиотекой фильтрации данный
Все указанные библиотеки идут без лишних зависимостей - всё только самое необходимое для их работы.

Точка внутри многоугольника

Допустим есть многоугольник из N (и это главное) вершин. И есть точка в произвольном месте. Необходимо определить принадлежит она ему или нет. Точки представлены в виде структуры:
struct point{ unsigned int x; unsigned int y;};
Все решения и алгоритмы которые я находил были написаны для четырехугольников и для треугольников. Главное уточнение многоугольник может быть выпуклый и не выпуклый.
Я остановился на идеи подсчитать сколько сторон луч выпущенный из точки пройдет. если четное число - не в многоугольнике. если не четное - в многоугольнике. То есть нам надо указывать вершины по часовой стрелке. Сделать структуру сторон. Но как проверять? Как расчитать эти стороны и сделать пересечение?


Ответ

Плохо ищете.
bool result = false; int j = size - 1; for (int i = 0; i < size; i++) { if ( (p[i].Y < point.Y && p[j].Y >= point.Y || p[j].Y < point.Y && p[i].Y >= point.Y) && (p[i].X + (point.Y - p[i].Y) / (p[j].Y - p[i].Y) * (p[j].X - p[i].X) < point.X) ) result = !result; j = i; }
p - список точек size - количество точек result - входит ли точка в многоугольник
Первая строка условия проверяет попадание point.Y между значениями p[i].Y и p[j].Y, контролирует направление прохода вершины и обеспечивает ненулевой знаменатель основной формулы.
Вторая строка проверяет нахождение стороны p[i]p[j] слева от точки point
Третья строка формирует отрицательный ответ при чётном количестве сторон слева и положительный — при нечётном.

Алгоритм метода count в Python 3

Какой алгоритм использовали разработчики в методе count для строки в Python 3? Какая сложность этого алгоритма?


Ответ

Для стандартной реализации интерпретатора Python, т.е. CPython, насколько я понимаю, верно следующее:
Для поиска количества вхождений паттерна в строку используется алгоритм Бойера — Мура. Так как count возвращает количество неперекрывающихся вхождений подстроки в строку, то сложность работы алгоритма Бойера — Мура будет составлять O(n + m), где n + m — это сумма длин строки и паттерна.

Я не очень хорошо разбираюсь в структуре исходного кода CPython, но очень похоже, что метод count действительно описан в файле count.h, приведённом @Suvitruf. Функция, описанная в нём, содержит единственный вызов -- вызов функции FASTSEARCH, описание которой я нашёл в файле fastsearch.h, которая содержит вариант алгоритма Бойера — Мура.

Источники:
исходный код count.h исходный код fastsearch.h описание алгоритма Бойера — Мура и его вариаций на википедии

Статическая константа

Можно ли объявить с инициализацией static переменную типа double/float и производных внутри класса?
Если да, то каким способом? Если нет, то почему?


Ответ

Вы можете создавать константные статически члены класса со спецификатором constexpr и инициализировать их внутри определения класса.
Например
#include
struct A { static constexpr double d = 10.15; };
constexpr double A::d;
int main() { A a;
std::cout << a.d << std::endl;
return 0; }
Ранее этого нельзя было делать, так как тип double разными компиляторами представлялся по-разному и более того было расхождение между препроцессорами и компиляторами, как они представляют тип double
Вот, что, например, пишет Страуструп в своем предложении по включению в стандарт спецификатора constexpr
Traditionally, evaluation of floating-point constant expression at compile-time is a thorny issue

tan и бесконечность

Может ли tan возвратить бесконечность? При каком значении? pi/2 не возвращает бесконечность (из за погрешностей, наверно).


Ответ

Нет, tan не может вернуть бесконечность (+Inf или -Inf).
Из примечания к описанию tan в cppreference
У функции есть полюса при x = π(1/2 + n), однако существующие реализации чисел с плавающей точкой не могут точно представить π/2, поэтому аргумент никогда не попадает в полюс.

Можно ли как то добавить в свое приложение типовое окно для загрузки файлов?

Хотелось бы узнать можно ли сразу подключить типовое окно для загрузки файлов ( например такое же как используется при прикреплении документа к письму в электронной почте) или же все это нужно прописывать вручную? И каким образом это можно реализовать?


Ответ

Да, можно. В WinAPI - совершенно точно GetOpenFileName, в .NET - OpenFileDialog, судя по google.

Различие анонимных методов и lambda

В чем различие между анонимными методами и lambda-выражениями? В анонимных методах мы можем обойтись без параметров, если даже это и ожидается:
public event EventHandler SomeEvent; ... SomeEvent += delegate { Console.WriteLine("some information") };
Какие еще есть плюсы/минусу у анонимных методов и lambda-выражениями?


Ответ

Разница в том, что лямбда, в зависимости от контекста использования, может быть скомпилирована в две совершенно разных вещи:
Если контекст подразумевает использование лямбды как анонимного метода - лямбда компилируется в анонимный метод.
Func filter = x => x > 2;
будет превращено компилятором в то же, во что он превратит
Func filter = delegate(int x) { return x > 2 };
Т.е. в этом варианте использования - лямбды - это просто сокращенный вариант старого синтаксиса анонимных методов. Именно в таком виде они внедрены в Java / C++ и остальных языках, которые "добавили лямбды" за последние пару лет.
В той же Java лямбды - это единственный способ объявить анонимный метод. До введения лямбд в Java были анонимные классы (анонимные реализации интерфейсов), но не было анонимных методов - что сделало написание современного кода с промисами (аналогом Task) дико неудобным. Введение анонимных методов ("лямбд") значительно упростило написание цепочек тасков с коллбеками.
В C# синтаксис анонимных методов был введен в 2.0, в 2005-ом году, цепочки промисов можно делать уже больше десяти лет, так что что лямбды в качестве альтернативного синтаксиса ключевому слову delegate картины не изменили. Вводились лямбды совсем не ради него.
В этом варианте использования различия между лямбдами и delegate {} минимальны - на уровне "тут меньше скобок". Никаких принципиальных различий или значительных преимуществ между двумя синтаксисами нет.

Если контекст подразумевает использование лямбды в виде значения типа Expression, то лямбда компилируется не в анонимный метод, а объект-композит, представляющий код лямбды в виде AST:
Expression> filter = x => x > 2;
превращается в
ParameterExpression paramX = Expression.Parameter(typeof(int));
Expression> filter = Expression.Lambda>( Expression.GreaterThan( paramX, Expression.Constant(2) ), paramX );
Такое представление позволяет в рантайме преобразовывать выражения из кода (x > 2) в код на другом языке (SQL: WHERE table.ColumnX > 2, OData: $filter=x>2).
Именно из-за этого варианта использования и ввели лямбды в C#, и именно за счет него работают LINQ-провайдеры вроде Entity Framework.

Увеличение кругов на CSS3

Почему при добавлении к .circle свойства scale он перестает выравниваться по центру?
.furniture-item { position: absolute; width: 100px; height: 100px; top: 50%; left: 50%; transform: scale(4); transform-origin: 50%; background-color: rgba(110, 100, 204, 0.5); border-radius: 50%; cursor: pointer; z-index: 1; transition: transform 1s; } .circle { position: absolute; opacity: 1; width: 25px; height: 25px; top: 50%; left: 50%; transform: translate(-50%, -50%); transform-origin: 50%; border-radius: 50%; background-color: rgba(0, 100, 204, 0.5); z-index: 1; }


Пример


Ответ

Трансформации применяются последовательно - масштабирование нужно применять после сдвига.
transform: translate(-50%, -50%) scale(2);
.furniture-item { position: absolute; width: 100px; height: 100px; top: 50%; left: 50%; transform: scale(4); transform-origin: 50%; background-color: rgba(110, 100, 204, 0.5); border-radius: 50%; cursor: pointer; z-index: 1; transition: transform 1s; } .circle { position: absolute; opacity: 1; width: 25px; height: 25px; top: 50%; left: 50%; transform: translate(-50%, -50%); transform-origin: 50%; border-radius: 50%; background-color: rgba(0, 100, 204, 0.5); z-index: 1; }


Зачем нужен атрибут [Serializable] и что он делает?

У всех классов, экземпляры которых должны/могут быть сохранены через BinaryFormater, обязан быть этот самый атрибут [Serializable]. Зачем он нужен?
Нет, конечно, ясно, что он говорит среде CLR, мол, тип есть сериализуемый, поэтому, будь добра (среда) и сериализируй!
В моем представлении, почти на пальцах, этот атрибут помогает MSV дописать и реализовать GetObjectData(SerializationInfo info, StreamingContext context) из интерфейса ISerializable для каждого поля в классе. Например, так:
public override void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("Name", name); info.AddValue("BDate", BDate); info.AddValue("Price", Price); }
И реализовать конструктор для десериализации, вот так:
public Engineer(SerializationInfo info, StreamingContext context) : base(info.GetString("Name"), info.GetDateTime("BDate")) { Price = info.GetDecimal("Price");
}
НО, даже если и интерфейс ISerializable ты реализовал, то атрибут все равно нужен. CA2237: MarkISerializableTypesWithSerializable
Что же он все таки делает, так сказать, под капотом?


Ответ

В дополнение к ответу @Alexander Petrov, процитирую MSDN (в собственном переводе):
Применяйте атрибут SerializableAttribute к типу для того, чтобы указать, что экземпляры этого типа разрешено сериализовывать. Если хотя бы один тип в графе сериализуемых объектов (то есть, тип корневого объекта или любого объекта, на который он внутри ссылается прямо или косвенно) не имеет этого атрибута, CLR выбросит SerializationException
Это предотвращает ошибки, связанные с непредусмотренной сериализацией типов, которые для сериализации вовсе не предназначены.
Почему такое необходимо для бинарной сериализации? Дело в том, что бинарная сериализация нарушает инкапсуляцию и работает напрямую с закрытыми полями. При этом, в отличие от вызова сеттера для публичного свойства, легко может быть нарушен инвариант типа. Например, если каждый экземпляр класса получает при создании уникальный номер, то бинарная десериализация склонирует этот самый номер, нарушив тем самым логику программы.
Чтобы избежать таких проблем, для участия типа в сериализации CLR требует осознанного решения программиста о том, что каждый конкретный может быть безопасно сериализирован.
(Информация частично взята из этого ответа.)

Применение enum на реальных проектах

Применяют ли на реальных проектах перечисления enum? Если да, то в каких use-case? Я читал, что с данными типами в будущем могут появиться проблемы, связанные с управлением версиями (тут источник)
У меня есть класс ChessFigure, у которого есть свойство Colour. Хочу сделать перечисление "Black" и "White", но не уверен, что это нужно (альтернатива: свойство сделать типа bool и переименовать его в IsWhite).
UPD. Цель, которую я преследую - создать удобно поддерживаемую библиотеку классов.


Ответ

Да, конечно используется. Например, в проекте, над которым я сейчас работаю, ровно 125 enum'ов.
Из двух вариантов bool IsBlack или enum PieceColor { White, Black } второй вариант кажется мне более предпочтительным.
Например, вы не сможете при втором варианте случайно присвоить несвязанное булево значение: IsBlack = IsGameSaved скомпилируется, а Color = IsGameSaved — нет.
Кроме того, если у вас функция выглядит как
void MakeMove(bool isBlack) { ... }
то глядя на код MakeMove(true), нужно ещё вспомнить, что же означает это самое true: белый цвет, чёрный, или вообще живого игрока в отличие от противостоящего ему искусственного интеллекта. С вызовом MakeMove(PieceColor.White) вопросов не возникает.
Так что да, для удобства лучше использовать enum'ы.

Метод в Python, выводящий все экземпляры своего класса

Как создать метод в Python, который будет выводить все экземпляры того же класса, в котором определен этот метод?


Ответ

Вот вариант в котором не течет память, и который поддерживает оборачивание нескольких классов.
Метакласс:
import weakref
class MyMeta(type): def __init__(self, *args, **kwargs): self.__instances = {} super(MyMeta, self).__init__(*args, **kwargs)
def get_instances(self): return list(self.__instances.values())
def delete(self, id_instance): del self.__instances[id_instance]
def __call__(self, *args, **kwargs): instance = super(MyMeta, self).__call__(*args, **kwargs) self.__instances[id(instance)] = weakref.proxy(instance) return instance
Использование (можно создать несколько таких классов, не копируя метакласс):
class MyClass(object, metaclass=MyMeta): def __del__(self): # этот метод и действие внутри него обязательно, иначе будет течь память под прокси self.__class__.delete(id(self))
print(MyClass.get_instances()) a = MyClass() b = MyClass() print(MyClass.get_instances()) del b print(MyClass.get_instances())

Обнуление кортежа в Python после применения sum

Вот так вывод кортежа происходит нормально:
l = (i for i in range(1,9) if i%2 == 1) print(*l)
Получаем на выводе 1 3 5 7
Но если попытаться сначала вывести сумму кортежа, то сумма выведется, но сам кортеж уже не отобразится:
l = (i for i in range(1,9) if i%2 == 1) print(sum(l)) print(*l)
На выводе получим 16 и пустую строку.
Если делать то же самое не с кортежем, а со списком, то все нормально. В чем причина странного поведения кортежа?


Ответ

Конструкция ... for ... in ... в круглых скобках порождает не кортеж, а генератор — объект, который используется для итерации всяких последовательностей. Ключевое отличие от списка — непосредственные вычисления производятся только по мере надобности, при получении каждого следующего элемента вызовом функции next. Итератор одноразовый однажды получив все значения, он будет пуст. Собственно говоря, это у вас и происходит вначале при вычислении суммы, затем уже ничего не остаётся для вывода на экран.
Давайте рассмотрим пример.
l = [2**i for i in range(2, 10)] g = (2**i for i in range(2, 10))
В первом случае все возведения в степень будут произведены в момент создания списка, а все созданные числа будут храниться в памяти. Может быть не очень рационально, если они будут использоваться только по одному разу.
Во втором случае, напротив, операция возведения в степень производится непосредственно в момент получения очередного элемента. Например, так
next(g) # вернёт 4 при первом вызове, затем 8 при втором, ...
Когда последовательность заканчивается, вызов next окончится исключением StopIteration. Это даёт однозначно выявить конец.

Помогите перевести мою задачу на стримы JAVA8 JAVA9

Учу сейчас стримы из Java 8 и JAVA 9. Проблема такая, как вначале пропустить строки файла после позиции END OF HEADER(предпоследняя строка файла), а затем считать каждое значение(оставшиеся цифры) и возможно ли мою задачу сделать на стримах?.
2.10 N: GPS NAV DATA RINEX VERSION / TYPE teqc 2017Feb10 UNAVCO Archive Ops 20170418 19:33:16UTCPGM / RUN BY / DATE 9.2160D+04 -1.1469D+05 -1.3107D+05 7.2090D+05 ION BETA 9.313225746155D-10 3.552713678801D-15 233472 1930 DELTA-UTC: A0,A1,T,W END OF HEADER 29 17 1 1 2 0 0.0 6.356909871101D-04-2.046363078989D-12 0.000000000000D+00
Начал делать так:
try { Files.lines(Paths.get("src/main/java/ab010010.17n"), StandardCharsets.UTF_8).// дальше что применять и множества методов?; } catch (IOException e) { e.printStackTrace(); }


Ответ

В Java9 появился метод потока dropWhile, серьёзно облегчающий вашу задачу:
Files.lines(Paths.get("src/main/java/ab010010.17n"), StandardCharsets.UTF_8) .dropWhile(s -> !s.contains("END OF HEADER")) .skip(1) .map(s -> s.split(" ")) .flatMap(Arrays::stream) .filter(i -> !i.isEmpty()) .forEach(System.out::println);

Найти матрицу-множитель в произведении матриц при известном результате

Имеется произведение матриц a*b=c. Причем произведение матриц - это результат numpy.dot, а не поэлементное произведение. Известны матрицы a и c. Требуется найти матрицу b. Каким образом это можно сделать в python, не прибегая к решению системы уравнений с множеством неизвестных? Если просто делить numpy.matrix, то получается совсем не тот результат.
Вот пример:
import numpy as np a = np.matrix([[ 1., 2.],[ 3., 4.]]) c = np.matrix([[ 2.],[ 1.]]) c/a Out[201]: matrix([[ 2. , 1. ], [ 0.33333333, 0.25 ]])
Решил письменно обратную задачу, получил ответ:
([[-3. ], [ 2.5]])
Проверяем:
b= np.matrix([[-3. ],[ 2.5]]) a*b Out[207]: matrix([[ 2.], [ 1.]])
Если переводить в ndarray, то то же самое получается:
c.getA()/a.getA() Out[213]: array([[ 2. , 1. ], [ 0.33333333, 0.25 ]])


Ответ

Воспользуйтесь обратной (inverse) матрицей
In [224]: b = np.linalg.inv(a) * c
In [225]: b Out[225]: matrix([[-3. ], [ 2.5]])
Это будет работать для объектов типа numpy.matrix. Если a и c - объекты типа numpy.ndarray, то нужно использовать dot product (как в ответе @MarianD):
In [8]: np.linalg.inv(a).dot(c) Out[8]: matrix([[-3. ], [ 2.5]])
PS использование dot product (операции умножения матриц как это понимается в линейной алгебре) - является более универсальным решением, т.к. оно правильно работает как для объектов типа numpy.matrix так и для numpy.ndarray
In [10]: np.linalg.inv(a.getA()).dot(c.getA()) Out[10]: array([[-3. ], [ 2.5]])

Пояснение:
A * B = C | умножим обе части на A-1
умножение матриц операция некомутативная, т.е. A * B != B * A, поэтому чтобы получилась единичная матрица будем делать так:
A-1 * A * B = A-1 * C
=>
B = A-1 * C
UPDATE: во многих случаях гораздо выгоднее решить систему уравнений, по сравнению с нахождением обратной матрицы (спасибо @jfs за подсказку):
In [328]: b = np.linalg.solve(a, c)
In [329]: b Out[329]: matrix([[-3. ], [ 2.5]])
Вот некоторые из преимуществ подхода решения системы линейных уравнений по сравнению с нахождением обратной матрицы:
решение СЛУ (системы линейных уравнений) дает более точные численные результаты по сравнению с методами, использующими перемножение матриц. Пример скалярного произведения возвращающего неточный результат при использовании разреженных матриц (sparse matrices) есть методы, позволяющие найти решение и возвращающие также разреженные матрицы (если это возможно), что существенно экономит использование памяти. Обратная же матрица в общем случае не будет разреженной и может занимать на несколько порядков больше памяти. Например разреженная матрица размерности 1.000.000 x 1.000.000 у которой всего 1.000.000 ненулевых элементов (например единичная матрица или такая, у которой в каждой строке/столбце по одному ненулевому элементу) легко поместится в памяти и займет приблизительно: объем памяти необходимый для данного типа (np.int8, np.int16, np.int32, np.int64, np.float64, etc.) плюс небольшие накладные расходы (информация о позиции ненулевых элементов в разреженной матрице). Если преобразовать такую матрицу в обычную или найти обратную ей то в результате надо будет хранить в памяти уже 1.000.000 x 1.000.000 = 1.000.000.000.000 (один триллион элементов, или около 3.6 TiB для 32-битных элементов)

Можно ли сделать так, чтобы объект класса создавался только путём выделения памяти в куче, а не на стеке?

MyClass o; // error MyClass * o = new MyClass; // ok


Ответ

Конечно, можно. Закройте его деструктор (сделайте его private).
Чтобы удалить выделенный динамически объект, вам придется написать отдельную функцию - например, друга или статический член - для удаления, вроде
friend void destroy(MyClass* t) { delete t; }
... MyClass * o = new MyClass;
... destroy(o);

Что может крутого сделать React.js чего не может jQuery [закрыт]

Всегда писал на jQuery. Но вот недавно сделал хелло ворлд на AngularJS, Angular2, React.js, Vue.js. И честно говоря не нашел в них ничего супер крутого. Скажите, пожалуйста, лучше с реальным примером — где jQuery проигрывает ReactJS. Желательно в связке с asp.net mvc/api


Ответ

В реакте другой подход к рендерингу интерфейса. Как любят говорить, интерфейс становится функцией от состояния. Вот это и есть круто. Накручивать реакт на мвц-модель на фронтенде я бы не стал (хотя долго пытался сделать это в связке с mobx). Одним днём, разбираясь с react-apollo (graphql клиент) мне открылось оно - react composition. В этот день, после более года работы с реактом, я, как мне кажется, действительно понял, что такое реакт.
Реакт позволяет абстрагироваться от DOM и в этом большой плюс. Тестировать значительно проще.
Важно понять, что мы входим (русское сообщество ещё, судя по всему, входит, а мировое уже вошло) в эпоху компонентного веба. jquery в него не вписывается. Не зря гугл пропагандирует свои WebComponents. На данный момент это, кажется, ещё более экспериментальная вещь. Тем не менее, однозначно можно сказать, что компонентам быть, а дёрганию дома селекторами не быть.
Реакт становится многократно лучше со следующими технологиями (без них, я бы сказал, бессмысленно его трогать):
0) (от xFloooo) react-loadable упрощает асинхронную подгрузку кода (code-splitting)
1) es6/typescript/flow. Лично я бы порекомендовал Typescript, т.к. библиотека типов значительно больше. Некоторые из них, к сожалению, не всегда оправдываю ожидания полностью, но в целом всё работает довольно хорошо. Наверное, не в strict режиме, дабы не играть в игру "убедим тайпскрипт, что наш код правильно написан).
Использование типизированного языка многократно облегчает задачу дебага реакт-компонентов, в ситуациях когда пропсы перебрасываются от одного компонента к другому, что может повторятся несколько раз подряд. тайпскрипт или флоу сразу же подскажут, какие пропсы поступают в неверном типе. Причём этот типа может быть не только простым скалярным, но и сложным интерфейсом.
2) storybook - чтобы работать над презентационными компонентами в вакууме (а не пытаться их сразу встроить в сайт). Это виртуальное полотно, где мы можем разместить компонент, над которым работаем и смотреть как он себя ведёт и программировать его. И подключать в проект, когда компонент написан, а не в процессе написания.
3) redux/mobx. рекомендую редакс, в основном из-за большой экосистемы и прозрачности работы. typescript-fsa - полностью типизированные экшны!
4) react-router и react-redux-router - практически безальтернативное решение маршрутизации в приложении
4) recompose и паттерны hoc/react-composition/render props
5) styled-components + polished или, возможно, css-in-js типа aphrodite
6) jest для тестирования (вы же пишете тесты?)
7) Для redux-а существует большое количество библиотек, из них я бы хотел выделить
redux-form для форм
redux-fractal / redux-ui для локального стейта контейнеров (можно с лёгкостью использовать копии одного и того же стора (стейт/экшены/редьюсеры) для нескольких контейнеров.
Ну и в довесок:
react-semantic-ui для прототипирования интерфейсов (а может и для продакшна, если настроить dead code elimination). Конечно же, это не единственная библиотека подобного характера, есть ещё antd, react-material-uiи дюжина других. Тот же бутстрап
react-sortable-hoc для быстрого dnd в рамках одного списка
classnames - швейцарский нож для соединения многих имён css классов в одну строку, когда присутствует сложная логика
Что вспомню - допишу

Как находить библиотеки с помощью CMake?

У меня в проекте используются библиотеки Boost и WebRTC. При попытке собрать проект возникает проблема со сборкой WebRTC вот скриншот.
CMakeLists.cmake:
cmake_minimum_required(VERSION 3.9)
project(webrtc-server)
if(EXISTS "${CMAKE_SOURCE_DIR}/LocalConfig.cmake") include(LocalConfig.cmake) else() message(FATAL_ERROR "Local config is absent") endif()
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic")
set (Boost_USE_MULTITHREADED ON) set (Boost_USE_STATIC_LIBS ON) set (Boost_USE_STATIC_RUNTIME OFF) set (BOOST_ALL_DYN_LINK OFF)
include(CMake/CMakeFindExtensions.cmake) include(CMake/CMakeHelpers.cmake) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
find_package(Boost 1.65.1 REQUIRED COMPONENTS program_options system) find_package(WebRTC REQUIRED)
include_directories(${Boost_INCLUDE_DIR}) include_directories(${WEBRTC_INCLUDE_DIR})
message(SOURSE " ${Boost_LIBRARIES}") message(SOURSE " ${Boost_INCLUDE_DIRS}")
if(Boost_FOUND) add_executable(webrtc-server src/webrtc_server.cpp src/webrtc_observers.h ) target_link_libraries(webrtc-server ${Boost_LIBRARIES} ${WEBRTC_LIBRARIES} ) endif()
LocalConfig.cmake:
set(BOOST_ROOT ExternalLibs/boost_1_65_1) set(WEBRTC_ROOT_DIR ExternalLibs/WebRTC)
Tree :
. ├── CMake │   ├── CMakeFindExtensions.cmake │   ├── CMakeHelpers.cmake │   └── FindWebRTC.cmake ├── CMakeLists.txt ├── ExternalLibs │   ├── boost_1_65_1 │   └── WebRTC ├── LocalConfig.cmake ├── README.md ├── scripts │   ├── install_boost.sh │   └── install_webrtc.sh ├── src │   ├── webrtc_observers.h │   └── webrtc_server.cpp └── temp
P.S. В шапке верная версия. Советую внимательно смотреть на регистр переменных - имеет очень важное значение.


Ответ

Поиск библиотек в CMake происходит с использованием базовых команд самого CMake, для поиска по файловой системе. Это такие команды как: find_path, find_library и т.д. Обычному пользователю, как правило, эти команды не нужны, потому что уже кто-то заранее написал скрипт CMake, состоящий из этих команд, который находит всю необходимую информацию по библиотеке/фреймворку.
Обычно такие скрипты имеют вид FindXXX.cmake, где XXX это имя библиотеки. Эти скрипты используются тогда, когда пользователь в своём CMake скрипте использует команду find_package. К примеру, find_package(Boost REQUIRED) ожидает найти файл FindBoost.cmake и когда находит его, то исполняет всё, что находится внутри этого файла.
CMake поставляется с целым набором таких файлов, которые можно найти в директории, где он установлен: share/cmake-xxx/Modules. Имея это список файлов мы можем посмотреть, что за библиотеки поддерживаются CMake из коробки, а также посмотреть, что могут потребовать соответствующие скрипты на вход, чтобы помочь найти ту или иную библиотеку.
Итак, мы перешили в эту директорию и нашли FindBoost.cmake. Благо этот скрипт имеет неплохую документацию, и из него мы сразу узнаём, что для помощи в нахождении boost, ему необходимо знать где находится папка с оным. Для этого он ждёт переменную BOOST_ROOT. Эта переменная может быть установлена как локально в скрипте CMake, так и глобально, как переменная окружения.
Т.е. для того, чтобы нам найти boost, мы можем написать следующее:
set(BOOST_ROOT /home/koshachok/proj/ExternalLibs/Boost_1_65_1) find_package(Boost REQUIRED COMPONENTS program_options system)
Но явно прописывать путь в общем файле это неправильно, лучше используйте переменную окружения или же некоторый обходной путь, который я опишу дополнительно позже.
Заметьте, что каждый скрипт уникален и то, что ожидает скрипт для boost, может отличаться от того, что требует другая библиотека. Поэтому всегда нужно смотреть документацию к скрипту, чтобы понять, чего он от тебя хочет. Если у скрипта хорошая документация, то всё сразу будет понятно. Если нет, тогда придётся из его содержимого понять самостоятельно, чего же он хочет (обычно это не так сложно).
Вооружившись всем вышеописанным идём искать FindWebRTC.cmake в директории CMake и не находим его. Что делать? Первым делом вбиваем в Яндекс FindWebRTC.cmake и, как правило, находим немало вариантов уже готового файла, один из котороых можно выбрать под свои нужды. Я взял первый попавшийся, и он ожидает установленной WEBRTC_ROOT_DIR в качестве помощи в поиске. Но как нам использовать этот файл, как сделать так, чтобы find_package его использовал? Очень просто: помещаем его в дерево исходников, скажем в 3rdParty/cmake. После чего добавляем в наш скрипт (до find_package) такую строку:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/3rdParty/cmake")
После чего, скрипт должен находиться и выполняться. Нам же остаётся использовать его результаты (WEBRTC_INCLUDE_DIR, WEBRTC_LIBRARIES).

Пару слов хочется сказать по поводу того, как и где прописывать полные пути к директориям библиотек, которые помогают скриптам в поиске. Для этого я использую следующий механизм. В основном скрипте CMake добавляем такой код:
if(EXISTS "${CMAKE_SOURCE_DIR}/LocalConfig.cmake") include(LocalConfig.cmake) else() message(FATAL_ERROR "Local config is absent") endif()
После чего добавляем файл LocalConfig.cmake со следующим содержимым:
set(BOOST_ROOT /home/koshachok/proj/ExternalLibs/Boost_1_65_1) set(WEBRTC_ROOT_DIR /home/koshachok/proj/ExternalLibs/WebRTC)
И, собственно, всё. Каждый разработчик просто создаёт свой локальный конфиг, который никак не мешает основному файлу CMake.

Выполнение php скрипта по расписанию без CRON

Всем привет, помогите пожалуйста решить задачу, на сайте есть еженедельный конкурс, каждый понедельник в 0:00 он должен начинаться, а каждое воскресенье в 23:59(или если возможно в 0:00), завершаться, и сразу после начисления приза начинался опять? Но вот как запускать php скрипт каждый понедельник в 0:00 без CRON, я не знаю... Подскажите пожалуйста решение проблемы.


Ответ

cron online, указываете ссылку на файл на своем ресурсе, который надо дергать в нужное время, ну и указываете время.

Найти максимальную возрастающую подпоследовательность

Есть задачка: Дана последовательность целых чисел. Найти ее максимальную возрастающую подпоследовательность. Нашла решение в интернете, но никак не могу вникнуть( +1000000 к карме тому, кто сможет мне объяснить принцип действия этой программы #include using namespace std;
/* Finds longest strictly increasing subsequence. O(n log k) algorithm. */ template vector find_lis(vector &a) { vector b, p(a.size()); int u, v;
if (a.size() < 1) return b;
b.push_back(0);
for (int i = 1; i < (int)a.size(); i++) { if (a[b.back()] < a[i]) { p[i] = b.back(); b.push_back(i); continue; }
for (u = 0, v = b.size()-1; u < v;) { int c = (u + v) / 2; if (a[b[c]] < a[i]) u=c+1; else v=c; }
if (a[i] < a[b[u]]) { if (u > 0) p[i] = b[u-1]; b[u] = i; } }
for (u = b.size(), v = b.back(); u--; v = p[v]) b[u] = v; return b; }
/* Example of usage: */ #include #include int main() { int a[] = { 1, 9, 3, 8, 11, 4, 5, 6, 4, 19, 7, 1, 7 }; vector seq(a, a+sizeof(a)/sizeof(a[0])); vector lis = find_lis(seq);
for (unsigned i = 0; i < lis.size(); i++) printf(i+1 < lis.size() ? "%d " : "%d
", seq[lis[i]]); getch(); return 0; }


Ответ

Смотрите, всё не так уж сложно. Код отлично написан с точки зрения мелочей имплементации, но конечно названия переменных и повторное их использование с другим смыслом не добавляет понятности алгоритму. Я переименовал переменные, разделил их где надо и снабдил комментариями. /* Finds longest strictly increasing subsequence. O(n log k) algorithm. */ template vector find_lis(vector &data) { // решаем задачу итеративно. сначала рассматриваем только первый элемент // затем добавляем элементы по одному
// (бывший массив p) // вот это интересная штука. тут для каждого индекса i мы рассматриваем // наилучшую из подпоследовательностей, заканчивающихся **на этом элементе**, // и записываем в этот массив индекс предыдущего элемента. // мы пользуемся таким важным свойством: для наилучшей подпоследовательности, // заканчивающейся на i-ом элементе, её кусок без финального элемента обязан быть // наилучшей подпоследовательностью, заканчивающейся на соответствующем // элементе. поэтому для хранения наилучших подпоследовательностей достаточно // лишь одного предыдущего индекса vector previdx(data.size());
// бывший массив b // а здесь мы храним индексы тех элементов, которые **в принципе** могут стать // чьим-то предыдущим элементом в наилучшей последовательности. // список хранится в таком порядке, чтобы соответствующие данные // были отсортированы (чтобы можно было искать двоичным поиском) vector possibleprev;
// тривиальный случай if (data.size() < 1) return vector();
possibleprev.push_back(0); // для одного элемента всё просто
for (int i = 1; i < (int)data.size(); i++) { // вводим в рассмотрение следующий элемент и обновляем списки
T curr = data[i];
// если новый элемент больше всех возможных предыдущих элементов... if (data[possibleprev.back()] < curr) { // ... то всё просто: его предыдущий элемент - наибольший из возможных previdx[i] = possibleprev.back(); // и он сам - тоже возможный наибольший для кого-то после possibleprev.push_back(i); continue; // всё, переходим к следующему элементу }
// теперь более интересный случай: мы попали в середину
int leftidx, rightidx;
// старый знакомый -- поиск половинным делением. // ищем в упорядоченном списке предыдущих элементов, // куда можно вставить новый элемент for (leftidx = 0, rightidx = possibleprev.size()-1; leftidx < rightidx;) { int mididx = (leftidx + rightidx) / 2; if (data[possibleprev[mididx]] < curr) leftidx=mididx+1; else rightidx=mididx; } int foundidx = leftidx;
if (curr < data[possibleprev[foundidx]]) { // нашли наш предыдущий индекс! // записываем найденное значение в таблицу previdx: if (foundidx > 0) previdx[i] = possibleprev[foundidx-1]; // и корректируем текущий список possibleprev // ключевой момент - теперь найденный элемент в таблице possibleprev // индекс больше не нужен possibleprev[foundidx] = i; } }
// отлично, собираем ответ. это будет последовательность индексов, // "связанная" через previdx vector bestsubseq(possibleprev.size()); // клёвый трюк с индексами, не знал раньше. // обратите внимание, начальное значение seqindex будет bestsubseq.size() - 1 for (int seqindex = bestsubseq.size(), dataindex = possibleprev.back(); seqindex-- != 0; dataindex = previdx[dataindex]) bestsubseq[seqindex] = dataindex; return bestsubseq; } Всё!

Собеседование по java [закрыт]

У меня на днях произойдет важное событие, мое первое собеседование по java se junior Хотелось бы услышать примерно список вопросов, возможно какие то хитрые вопросы, которые ставят джуниора в ступор( ну и ответы, если не сложно(= ) Я знаю что в интернете полно всего этого, вроде много прочитал, много выучил и все одно меня немного "трясёт" Заранее благодарен


Ответ

Пожалуйста, просмотрите ссылки, которые добавлены у меня в избранное. (Скоро сам пойду на собеседование, наверное). Многопоточность в Java Java собеседование. Коллекции Примеры с собеседований по Java на quizful Garbage Collection наглядно Несколько интересных вопросов с реальных собеседований Записки трезвого практика Будет отлично, если еще кто-то отпишется по теме.

Маппинг классов в C# по имени свойств?

Как на C# или через LINQ сделать такое:
class A { public string First { get; set; } public string Second { get; set; } //... //другие свойства };
class B { public string Third { get; set; } public string Four { get; set; } //... //другие свойства };
class Result { public string First { get; set; } public string Second { get; set; } public string Third { get; set; } public string Four { get; set; }
//... //другие свойства };
Как примапить A & B к Result?
Можно конечно написать вручную:
r.First = a.First; r.Second = a.Second; r.Third = b.Third; r.Four = b.Four;
Но так слишком много писать, хотелось бы по короче и побыстрее.


Ответ

Ответы-ссылки тут не приветствуются, но в этом случае без ссылки никак: AutoMapper
Package Manager:
Install-Package AutoMapper
C#:
Mapper.CreateMap(); Mapper.CreateMap();
var a = new A() { First = "1", Second = "2" }; var b = new B() { Third = "3", Four = "4" };
var res = Mapper.Map(a); Mapper.Map(b, res); // 1, 2, 3, 4
или с динамическим маппингом:
var a = new A() { First = "1", Second = "2" }; var b = new B() { Third = "3", Four = "4" };
var res = Mapper.DynamicMap(a); Mapper.DynamicMap(b, res);

Отображение кириллицы в CLion

Нужна помощь: не отображается кириллица в терминале CLion. Вот так выглядит надпись "Привет, Мир!":
╨Я╤А╨╕╨▓╨╡╤В, ╨Ь╨╕╤А!
Вот что будет с кодировкой windows-1251
╧ЁштхЄ, ╠шЁ!


Ответ

Почему так происходит?
CLion по дефолту использует UTF-8 для хранения файлов с исходным кодом. Строка "Привет, Мир!" будет представлять собой последовательность (в файле с исходником):
D0 9F D1 80 D0 B8 D0 B2 D0 B5 D1 82 2C 20 D0 9C D0 B8 D1 80 21
Как видите, на 12 символов исходной строки, получили 21 байт (т.к. кириллические символы занимают больше одного байта).
Компилятор GCC по умолчанию читает исходники в кодировке UTF8, если не указать другую через ключ -finput-charset. Таким образом эта последовательность байтов в неизменном виде сохранится в исполняемый файл.
При запуске программы на исполнение, CLion использует стандартный cmd.exe, который по умолчанию скорей всего у вас работает в кодировке CP866. В которой наша последовательность байтов будет отображена как:
╨Я╤А╨╕╨▓╨╡╤В, ╨Ь╨╕╤А!
(что вы и видите в терминале CLion)

Что делать?
Вариант 1
Сменить кодировку файла на IBM866 (то же, что и CP866) (настройки - File Encodings) (сам файл перекодировать, если там уже был текст на русском). Теперь кириллица будет сохраняться в файле с исходным текстом в кодировке CP866 (один байт на символ), в том же виде попадать в исполняемый файл и нормально отображаться в консоли CLion. Разумеется, использовать CP866 в 17-м году, без особых на то оснований, это некультурно. Кроме того придется ограничить себя только символами из CP866
Вариант 2
Вставить в начало свой программы:
system("chcp 65001");
или (потребует #include ):
SetConsoleOutputCP(CP_UTF8);
Консоль переключится в UTF-8, все будет отображаться как надо. Но только при использовании низкоуровневых операций вывода типа puts("Привет, Мир!");. Если выводить через std::cout, то возможен вывод типа ��ривет, Мир!. Это связано с тем, что Windows API для вывода в консоль ожидает видеть в каждом вызове законченную строку. И если оператор basic_ostream::operator<<(char*) для символа 'П' выполнит два API вызова (с D0 и 9F), то они не сольются в одну букву 'П', а будут интерпретированы и отображены как два разных символа (��).

Предостережение
При использовании UTF-8 в своей программе, например при хранении в std::string, следует помнить, что операции над строками могут дать не очевидные результаты (т.к. один символ теперь может занимать от 1 до 4 байтов).
Кроме вывода, аналогичные проблемы ожидают и при вводе из std::cin. Таким образом, единственное прозрачное решение для Windows (даже десятки), пока остается использование латиницы.

Yii2 подключение сторонней библиотеки

Я недавно начал изучать Yii2 и столкнулся с такой задачей:
Есть библиотека PhpWord, мне нужно её подключить, я делаю так в коде приложения
use PhpOffice\PhpWord\PhpWord; use PhpOffice\PhpWord\Autoloader;
Соответственно библиотека лежит в корне приложения в PhpOffice\PhpWord
Пространства имен класса вроде как совпадают, но почему-то класс не загружается PhpWord.
В чем может быть проблема?


Ответ

Установите класс через composer, тем более есть инструкция как это сделать: https://github.com/PHPOffice/PHPWord

Можно ли использовать Enum без необходимости постоянно кастовать?

Есть у меня перечисления. Очень большой список. Например:
enum State : byte { IDLE, //0 - стойка WALK_F, //1 - ходьба вперёд WALK_B, //2 - ходьба назад BLOCK, //3 - блок SIT, //4 - сидение JUMP_UP, //5 - прыжок вверх JUMP_F, //6 - прыжок вперёд JUMP_B, //7 - прыжок назад BLOCK_SIT, //8 - блок в присядке TURN, //9 - поворот RUN, //10 - бег. ... и т.д. };
Можно ли как-то применять эти значения в виде, представленным ниже?
byte test = State.RUN;
Или мне постоянно придется писать приведение к типу? Типа:
byte test = (byte)State.RUN;
Вроде бы если enum является перечислением из одного типа, то можно написать
enum ENUM_NAME : TYPE { ... };
и должно все работать. Но IDE упорно говорит что все равно надо кастовать. Может я что-то не понимаю.
Просто делать такое приведение типа абсолютно везде чересчур затратно. особенно если я решу тип сменить. Таких мест будет сотня. Тем более, если я заранее говорю, что у меня в перечислении будет всё одного конкретного типа, то почему бы такому не работать?


Ответ

Язык вам тонко намекает, что кастовать туда-сюда между enum и целым типом — не самая здравая и строго типизированная мысль. Вам не должно хотеться повсеместно использовать тип byte, если у вас есть enum с базовым типом byte
Просто используйте сам enum везде, где можно. Где нельзя — преобразуйте тип. И этой операции положено быть явной, потому что вы меняете тип переменной.
При этом какой у перечисления базовый тип — значения не имеет. Хоть enum Foo : int преобразовывать к int, хоть enum Bar : byte преобразовывать в byte — операция должна быть явной.

Односвязный список, удаление элемента, C++

Добрый день. Есть вот такой код удаления элемента из списка
void del(int n) // n - позиция удаляемого элемента { // Mass - объекты, которые хранятся в списке Mass *temp = HEAD, *helping = temp;
if ((temp != NULL) && (n <= size) && (n >= 0)) // если по этому номеру что-то лежит и этот элемент внутри списка { for (int i = 0; i < n; i++) { helping = temp; // предыдущее значение temp temp = temp->Next; }
if (temp == HEAD) // если элемент который надо удалить первый { helping = temp; temp = temp->Next; HEAD = temp; cout << "Удаляемый элемент: " << *helping; free(helping); size--; // уменьшаем размер списка return; } else // иначе, если он в середине или конце { // 0 1 2 3 4 // вводится, к примеру, 2. т.е. helping = 1, temp = 2; free(temp); size--; // 0 1 .. 3 4 helping->Next = helping->Next->Next; // т.е. теперь 1 указывает не на 2, а на 3. } }
Начало отрабатывается хорошо, т.е. первый элемент он удаляет, а вот другие элементы почему-то не получается. Думаю над этим уже второй день, голова кипит. Представляю себе алгоритм так:
Удаляем элемент Смещаем остальные элементы списка (слева к удаляемому или справа?)
или вообще сделать так 1. Удаляем элемент
Проходим весь список пока не наткнемся на удаленный (NULL) Перебрасываем ссылку с элемента перед удаленным на элемент после удаленного (минуя сам удаленный элемент) Повторяем п.3 пока не будет нулевых элементов. Учитывая, что конец списка мы не рассматриваем.

Всем огромное спасибо за помощь! Открыл много нового для себя в работе с указателями. Отдельное спасибо
@MichaelPak за указание направления в которую стоит копать и указания конкретной ошибки и подробного объяснения,
@Mike за то, что поругал за использование нерационального алгоритма
@alexolut за то, что подсказал разницу в между ned delete и malloc free
@Vlad from Moscow за подробное решение задачи и классную идею о использовании переменной беззнакового типа (так и сделал в итоге).
Я вам очень благодарен, спасибо большое!


Ответ

В принципе у вас написано все правильно за исключением двух моментов.
Первое - это номер удаляемого элемента не может быть равен size . size всегда на единицу больше, чем номер последнего существующего элемента, так как нумерация элементов у вас начинается с 0.
Поэтому вместо условия
if ((temp != NULL) && (n <= size) && (n >= 0)) // если по этому номеру что-то лежит и этот элемент внутри списка
вам следует написать
if ((temp != NULL) && (n < size) && (n >= 0)) // если по этому номеру что-то лежит и этот элемент внутри списка ^^^^^^^^
Вы бы облегчили себе жизнь, если бы переменная size имела беззнаковый целый тип. В этом случае не было бы необходимости проверять, что n >= 0. Вы могли бы size объявить, как имеющую тип unsigned int или, как обычно принято, size_t
Второе - это вы пытаетесь обратиться к уже удаленному элементу в предложении
helping->Next = helping->Next->Next;
Следовало сначала установить значение поля Next, а лишь затем удалять элемент.
С учетом сказанного функция может выглядеть следующим образом
void del(int n) // n - позиция удаляемого элемента { if ((HEAD != NULL) && (n < size) && (n >= 0)) // если по этому номеру что-то лежит и этот элемент внутри списка { // Mass - объекты, которые хранятся в списке Mass *temp = HEAD, *helping = HEAD;
for (int i = 0; i < n; i++) { helping = temp; // предыдущее значение temp temp = temp->Next; }
if (temp == HEAD) // если элемент который надо удалить первый { HEAD = temp->Next; } else { helping->Next = temp->Next; } cout << "Удаляемый элемент: " << *temp; free(temp); size--; // уменьшаем размер списка } }

арифметика указателей

Вопрос по поводу арифметики указателей С. Пусть
int *p; int *q; int *o; int i; o = NULL;
Допустим p и q указывают на разные элементы одного массива. Допустимы выражения (i, естественно, где-то определено):
p+i; q-i; p-q;
А допустимо ли:
p-o; o-p;
И что получится, если допустимы? Т.е. с одной стороны o не указывает на тот же массив и вроде нет, но он же равен и обычному 0, и первое вроде бы да.


Ответ

Нет, не допустимы
Стандарт С++ говорит (С++11 [expr.add]p6), что если два указателя не принадлежат одному массиву, то поведение не определено.
Результат вычитания двух указателей - это количество элементов между ними. Если p не выровнен на sizeof(int), то выражение p-o должно вернуть дробное количество элементов, чего не может быть.
При этом выражение p-NULL может быть валидно только если NULL - это #define NULL 0, и не валидно если, например, NULL определено как (void*)0 (в Си). Поскольку стандарт не говорит как именно должен быть определен NULL, то следует считать, что выражение p-NULL не валидно.
Примечание: выражение p-0 валидно и равно p, но это работает только для целого числа 0

Категории итераторов

Столкнулся с книжкой Л.Аммерааль STL. В начале этой книги столкнулся с категориями итераторов и мне стало непонятно что они значат? Объясните что собой представляют категории итераторов и в чем их отличия, а то есть категорий:
входной выходной прямой двунаправленный произвольного доступа


Ответ

Категории итераторов определяют действия которые можно сделать с итератором.
Если итераторы использовали бы виртуальные функции, то категории итераторов были бы абстрактными интерфейсами, которые наследовались бы друг от друга:
интерфейс InputIterator { ... }; интерфейс OutputIterator { ... }; интерфейс ForwardIterator : InputIterator, OutputIterator { ... }; интерфейс BidirectionalIterator : ForwardIterator { ... }; интерфейс RandomAccessIterator : BidirectionalIterator { ... };
InputIterator (входной)
Копирование, присваивание. Операции сравнения на равенство == и != Инкремент: ++iter и iter++ Разыменование для чтения: *iter и iter->m, при этом запрещена запись: *iter = value;
Пример входного итератора - это итератор чтения из потока: std::istream_iterator
OutputIterator (выходной)
Копирование, присваивание. Инкремент: ++iter и iter++ Разыменование для записи: *iter = value и *iter++ = value, при этом запрещено чтение.
Пример выходного итератора - это итератор записи в поток: std::ostream_iterator
ForwardIterator (прямой)
Все операции InputIterator и OutputIterator Требование многопроходности: если i1 == i2, то ++i1 == ++i2, т.е. итератор можно копировать, и обходить им последовательность много раз.
Прямые итераторы - это итераторы односвязных списков, например std::forward_list
BidirectionalIterator (двусторонний)
Все операции ForwardIterator Декремент: --iter, iter--, *iter--
Пример: итераторы двусвязных списков (std::list), деревьев (std::set).
RandomAccessIterator (произвольного доступа)
Все операции BidirectionalIterator Операции сравнения: i1 < i2, i1 > i2, i1 <= i2, i1 >= i2 Сложение/вычитание с числом: iter + n, iter += n, iter - n, iter -= n Разность итераторов: i2 - i1 Индексирование: iter[n]
Пример: итераторы массивов (std::vector), указатели.

Telegram API - Отправка Emoji

как отправлять emoji смайлики через API Telegram?
В официальной документации ни слово про смайликов. Где-то пишут, что нужно отправлять UTF-8 код смайлика....но все без толку
U+1F601 U1F601 #1F601; F601; \xF0\x9F\x98\x81


Ответ

Посмотрите на Emoji Unicode Tables Нужный вам код смайлика находится в колонке Bytes (UTF-8).
Перед отправкой на сервер необходимо выполнять URL Encode.
Например, \xF0\x9F\x98\x81 должен выглядеть так: %F0%9F%98%81

Освобождается ли память, выделенная под переменную ссылочного типа, которая объявлена внутри метода?

Допустим, имеется метод внутри класса:
public ICollection GetData() { ICollection rezult; var tempCollection = context.Get(); //doing some stuff; return rezult; }
Как ни крути, мне в коде нужна эта временная переменная. Вопрос состоит в том, нужно ли "занулять" эту переменную (tempCollection = null;), чтобы GC при сборке мусора понял, что она уже не нужна, или же это и так будет понятно, посколько она объявлена внутри метода?


Ответ

При завершении метода все его локальные переменные пропадают (если только не были захвачены замыканием). Отдельно занулять их не нужно.

Зачем нужны Lambda-функции?

Изучая Python, наткнулся на lambda-функции. Но нигде я пока не нашел примера, где они действительно нужны - только элементарные примеры вида print(lambda x, y: x**2 + y**2), где вполне можно убрать функциональную обертку. Для чего они действительно нужны и полезны?


Ответ

Они не могут быть 100% нужны, то есть без операций сложений написать программу нельзя, без лямбда-функций - можно, но с ними короче и удобней. Например, нужно напечатать словарь в порядке убывания суммы каждого значения:
bigrams = {"AB": [10, 11, 12], "BC": [5, -5, 8], "CD": [105, 1, 0], "DE": [6, 6], "EF": [15, 20, 15], "FG": [22, 11, 32], "GH": [20, 20, 20]} sorter = sorted(bigrams, key=lambda key: sum(bigrams[key]), reverse=True)
for key in sorter: print(key, bigrams[key])
Иначе нужно написать функцию:
from functools import partial
def sort_func(key, dict): return sum(dict[key])
bigrams = {"AB": [10, 11, 12], "BC": [5, -5, 8], "CD": [105, 1, 0], "DE": [6, 6], "EF": [15, 20, 15], "FG": [22, 11, 32], "GH": [20, 20, 20]} partial_sort = partial(sort_func, dict=bigrams) sorter = sorted(bigrams.keys(), key=partial_sort, reverse=True)
for key in sorter: print(key, bigrams[key])
Результат одинаков, но с лямбдой короче, не нужно искать глазами sort_func - сразу ясно, как именно сортируется коллекция. В стандартной библиотеке полно функций, которые принимают другие функции: map, reduce, filter, sorted, any, all
Можно написать замыкание:
def addition(x): return lambda y: x + y add_to_ten = addition(10) print(add_to_ten(8)) print(add_to_ten(6))
По идее, лямбда функции абсолютно то же самое, что и обычные функции, но без имени:
def func(x): func = lambda x: x + 1 return 100
import dis print(dis.dis(func))
показывает, что действительно создается новая функция, без обмана.

Как предотвратить ввод значений ниже нуля?

Здравствуйте, я новичек в этой сфере и поэтому все еще учусь простым вещам.
Делаю программу, чтобы хранила сведения о продуктах в одном каталоге, но я не хочу чтобы можно было поставить негативную цену на продукт или сделать негативное кол-во продуктов на складе.
Вот мой код:
public enum ProductCategory { Electric, Household, Garden, Miscellaneous } class Product { // Properties private int productID; private string productName; private double unitPrice; private double unitsInStock;
// Get Product Categories public ProductCategory category { get; }
// Validator for Unit Price public double UnitPrice { get { return unitPrice; } set { unitPrice = value > 0.0 ? value : 0.0; } }
// Validator for Units In Stock public double UnitsInStock { get { return unitsInStock; } set { unitsInStock = value > 0.0 ? value : 0.0; } }
// Constructor public Product(int productID, string productName, ProductCategory category, double unitPrice, double unitsInStock) { this.productID = productID; this.productName = productName; this.category = category; this.unitPrice = unitPrice; this.unitsInStock = unitsInStock; }
// Default Constructor with Chaining public Product(int productID, string productName) : this(productID, productName, ProductCategory.Miscellaneous, 0.0, 0.0) { }
// Override which returns a string with full product information public override string ToString() { return "The product " + productName + " with ID " + productID + " costs " + unitPrice + " euro per unit. We have " + unitsInStock + " items left in our " + category + " stock."; } }
//Testing the app class TestProduct { static void Main(string[] args) { // Assigning correct properties to the product Product p1 = new Product(1234567, "Cake", ProductCategory.Miscellaneous, 7.5, 150); Product p2 = new Product(2345678, "Drill", ProductCategory.Household, -23, 2); Product p3 = new Product(3456789, "Shovel", ProductCategory.Garden, 12.7, -10);
Console.WriteLine(p1); Console.WriteLine(p2); Console.WriteLine(p3);
Console.ReadLine(); } }
Вот что выдает консоль:
The product Cake with ID 1234567 costs 7.5 euro per unit. We have 150 items left in our Miscellaneous stock. The product Drill with ID 2345678 costs -23 euro per unit. We have 2 items left in our Household stock. The product Shovel with ID 3456789 costs 12.7 euro per unit. We have -10 items left in our Garden stock.
Как вы видите у меня цена на Drill -23 евро, а количество Shovel на складе -10.
Как сделать так, чтобы при негативных цифрах возращало 0?


Ответ

У вас уже вроде всё сделано. Просто в конструкторе присваивайте значения не полям метода, а свойствам:
//this.unitPrice= unitPrice; this.UnitPrice= unitPrice;`

Проверить правильно ли вложены скобки 〈 ( { [ ] } ) 〉в тексте

Вот пример, где скобки 〈 п{р}авильно (вло[ж]ены)〉. Вот пример, где скобки НЕ 〈 пр(авильно вложены〉).


Ответ

Классическое решение с использованием стэка, который сохраняет типы (несбалансированных) открывающих скобок:
Для каждого символа в тексте проверить является ли он открывающей скобкой если является, то добавить в стэк тип этой скобки (угловая/круглая/итд) если нет, то проверить является ли символ закрывающей скобкой если является и последняя добавленная открывающая скобка совпадает, то убрать её из стэка (найдена совпавшая пара скобок) иначе завершить алгоритм—найдена неправильно вложенная скобка.
Продолжать до конца текста и если стэк пустой, то текст содержит только правильно вложенные скобки.
На Питоне 3:
def is_balanced(text, brackets="〈〉()[]{}"): opening, closing = brackets[::2], brackets[1::2] stack = [] # keep track of opening brackets types for character in text: if character in opening: # bracket stack.append(opening.index(character)) elif character in closing: # bracket if stack and stack[-1] == closing.index(character): stack.pop() # remove the matched pair else: return False # unbalanced (no corresponding opening bracket) or # unmatched (different type) closing bracket return (not stack) # no unbalanced brackets
В этом случае тип скобки (фигурная/квадратная/итд) представлен индексом в opening списке, содержащим все открывающие скобки. closing содержит закрывающие скобки тех же типов на тех же индексах.
Пример:
>>> is_balanced('скобки 〈 п{р}авильно (вло[ж]ены)〉') True >>> is_balanced('скобки НЕ 〈 пр(авильно вложены〉)') False

Обязательно ли использовать модификаторы доступа в Java?

Везде наблюдаю использование private. Зачем? Это же твоя программа, объявил её public и все. Зачем все это вообще?


Ответ

@m-vokhm надеюсь это вы написали или не подумамши или спросонья...
Первичная задача модификаторов доступа отнюдь не в разграничении доступа разных девелоперов, а в идее инкапсуляции, которая преследует 2 цели:
механизм для ограничения прямого доступа к некоторым компонентам объекта механизм, который облегчает связывание данных с методами/функциями, которые работают с этими данными
Приведу простой пример: посмотрите на свои белые рученьки - у большинства из вас на запястье имеются часики, у кого-то механические, у кого то электронные, у кого-то смартвотчи. Для простоты примера рассмотрим механические часики.
public функция у часов одна: показывать время, иногда дату, иногда еще что-то. publicметодов у часиков всего несколько: подвести время, завести/зарядить - всё
Внутри часиков имеется огромное количество механизмов, шестеренок, винтиков, гаечек, иногда процессоров - да мало ли чего. Все это таинство скрыто от вас и обозначено как private. Почему то никому не приходит в голову идея, все эти шестереночки объявить public - представляю что произойдет, если все эти шестеренки сделать публичными - 99% часов в мире немедленно сломаются :) - очумелые рученьки людей которые ничего не понимают в часовых механизмах, в премудростях балансиров, маятников, регуляторов, анкерных спусков и проч. - немедленно все испортят...
Конечно есть мастера - часовщики, которые знают как надо использовать анкерные спуски и к какой шестеренке что должно быть прикреплено - в нашем случае это те самые девелоперы, которые и знают как работать с private/protected членами.
Надеюсь изложил понятно.

Как узнать размер объекта?

Какие есть способы получить размер объекта в памяти? Можно не обязательно в рантайме (кодом).


Ответ

Можно использовать WinDBG с psscor4.dll для платформы .NET (ещё есть Son of Strike но для Вашей задачи достаточно psscor4 (для CLR версии 2.* нужно взять psscor2)).
Запускаем WinDbg от имени администратора желательно. Аттачимся к нашему процессу. Загружаем psscor4: .load C:\Symbols\Psscor4\x86\x86\psscor4.dll - путь тут нужно подставить свой. Ищете Ваш объект. Тут есть несколько способов, например, самый простой для простых тестов памяти это выполнить команду !DumpHeap и вы увидите например такое: Дальше выполняем команду !DumpHeap /d -mt 00414da0, где 00414da0 - адрес Вашего объекта. И видим: И последний шаг (в этом простом примере): это выполнить команду получения размера объекта по его адресу: !objsize 0df73294, где 0df73294 - адрес объекта. И видим:
Мой код для теста:
public static class Program { private static void Main() { MyObject myObject = new MyObject { S = "1234567895555555555555555555555555555555", Type = 0 };
Console.ReadKey(); // не забудьте приаттачится в нужный момент.
Console.WriteLine(myObject); } }
public class MyObject { public int Type { get; set; } public string S { get; set; } }

Как печатать каждый n-ый элемент массива в ruby?

Как печатать каждый n-ый элемент массива в ruby?


Ответ

Например, вот так:
arr = [1, 2, 3, 4, 5, 6] n = 3
for i in (n-1..arr.length - 1).step(n) puts arr[i] end
Или же так:
(n-1..arr.length - 1).step(n) do |i| puts arr[i] end
Или ещё компактнее:
(n-1..arr.length - 1).step(n) { |i| puts arr[i] }
Вывод:
3 6

Как правильно работает Thread.Sleep(0)?

public void StartWork(Thread ThreadCopy) { while (ThreadCopy.IsAlive) Thread.Sleep(0); }
Правильно ли я понимаю, только когда в while придет false, тогда закончится метод StartWork?


Ответ

Для этого существует метод Thread.Join(). Такие циклы только загружают процессор, в то время как метод Join имеет нулевую нагрузку.
А по вопросу, да, ваш метод ждет, пока поток завершится.

В чём смысл существования reinterpret_cast?

В C++ существует оператор reinterpret_cast, смысл которого заключается в приведении между типами, несовместимыми друг с другом.
Однако подобные преобразования нарушают strict aliasing rule, что провоцирует неопределённое поведение. Те же преобразования, которые этого правила не нарушают, укладываются в const_cast, static_cast и dynamic_cast
В чём же тогда заключается смысл существования данного оператора, если его использование нарушает стандарт?


Ответ

reinterpret_cast используется не только для преобразования указателей одного типа в другой. Существует несколько разных преобразований. cppreference.com выделяет 11 вариантов преобразований:
В свой собственный тип Указателя в интегральный тип Интегрального типа в указатель Типа std::nullptr_t в интегральный тип Указателя одного типа в указатель другого типа lvalue одного типа в ссылку на другой тип Указателя на функцию одного типа в указатель на функцию другого типа Указателя на функцию в void* Нулевого указателя любого типа в указатель любого другого типа rvalue указатель одного типа на функцию-член в указатель другого типа на функцию-член rvalue указатель члена-данных одного типа в указатель ну другой член-данных другого типа
Type aliasing-правила затрагивают только пункты 5 и 6 и результат может быть безопасно использован (т.е. без нарушения strict-aliasing) в следующих случаях:
Результирующий тип есть динамический тип исходного объекта Результирующий тип и динамический тип указывают на одинаковый тип T Результирующий тип есть знаковый или беззнаковый вариант типа исходного объекта Результирующий тип есть агрегатный тип или union, в котором содержится элемент или нестатический член данных, используемый в качестве исходного объекта. Т.е. можно получить указатель на структуру по указателю на её член. Результирующий тип есть базовый класс динамического типа исходного объекта и этот тип является standard-layout классом и не содержит нестатических членов-данных, и результирующий тип - первый базовый класс. Результирующий тип есть указатель на char, unsigned char или std::byte
Некоторые реализации ослабляют эти правила в качестве нестандартных расширений языка.

Ругается на ломбок

Здравствуйте, подскажите в чем причина ошибки. Ругается на ломбок. Не знаю в чем причина, установлена jdk 9
Warning:(9, 8) java: lombok.javac.apt.LombokProcessor could not be initialized. Lombok will not run during this compilation: java.lang.IllegalArgumentException: com.sun.tools.javac.api.ClientCodeWrapper$WrappedStandardJavaFileManager extends com.sun.tools.javac.api.ClientCodeWrapper$WrappedJavaFileManager implements javax.tools.StandardJavaFileManager at lombok.javac.apt.LombokFileObjects.getCompiler(LombokFileObjects.java:130) at lombok.javac.apt.InterceptingJavaFileManager.(InterceptingJavaFileManager.java:40) at lombok.javac.apt.LombokProcessor.placePostCompileAndDontMakeForceRoundDummiesHook(LombokProcessor.java:164) at lombok.javac.apt.LombokProcessor.init(LombokProcessor.java:85) at lombok.core.AnnotationProcessor$JavacDescriptor.want(AnnotationProcessor.java:87) at lombok.core.AnnotationProcessor.init(AnnotationProcessor.java:140) at lombok.launch.AnnotationProcessorHider$AnnotationProcessor.init(AnnotationProcessor.java:69) at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.(JavacProcessingEnvironment.java:675) at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(JavacProcessingEnvironment.java:774) at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:869) at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.access$2200(JavacProcessingEnvironment.java:108) at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1206) at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1315) at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1246) at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:922) at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:100) at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:142) at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:96) at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:90) at org.jetbrains.jps.javac.JavacMain.compile(JavacMain.java:190) at org.jetbrains.jps.incremental.java.JavaBuilder.compileJava(JavaBuilder.java:473) at org.jetbrains.jps.incremental.java.JavaBuilder.compile(JavaBuilder.java:328) at org.jetbrains.jps.incremental.java.JavaBuilder.doBuild(JavaBuilder.java:255) at org.jetbrains.jps.incremental.java.JavaBuilder.build(JavaBuilder.java:208) at org.jetbrains.jps.incremental.IncProjectBuilder.runModuleLevelBuilders(IncProjectBuilder.java:1260) at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:937) at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:1009) at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:900) at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks(IncProjectBuilder.java:733) at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild(IncProjectBuilder.java:385) at org.jetbrains.jps.incremental.IncProjectBuilder.build(IncProjectBuilder.java:192) at org.jetbrains.jps.cmdline.BuildRunner.runBuild(BuildRunner.java:138) at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:295) at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:125) at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler.lambda$channelRead0$0(BuildMain.java:236) at org.jetbrains.jps.service.impl.SharedThreadPoolImpl.lambda$executeOnPooledThread$0(SharedThreadPoolImpl.java:42) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:514) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.base/java.lang.Thread.run(Thread.java:844)


Ответ

По умолчанию, ломбок добавляет @javax.annotation.Generated("lombok")ко всем сгенерированным методам.
Начиная с новой jdk эта аннотация больше не является стандартной.
Необходимо добавить в корень проекта lombok.config файл и внутри прописать: lombok.addJavaxGeneratedAnnotation = false

как конвертировать int в 16 ричную систему?

Добрый день нужно на сервер отправлять данные ф формате 16 речной системы ASCII.К примеру -1 как FFFFFFFF соответсвенно -2 как FFFFFFFE
что это за fff-ки?как конверитровать int a =-1 в FFFFFFFF?
Спасибо за внимание


Ответ

Данный вид записи называется дополнительный код. В Java можно получить такую запись стандартными средствами:
Integer.toHexString(1); // 1 Integer.toHexString(2); // 2 Integer.toHexString(-1); // ffffffff Integer.toHexString(-2); // fffffffe
Если нужно запись положительных чисел дополнить слева нулями до 8 символов, поможет String.format()
String.format("%8s", Integer.toHexString(123)).replace(' ', '0') // 0000007b

Бинарное дерево поиска на C/C++

Есть задачка. Имеется бинарное дерево. Требуется определить, является ли это дерево бинарным деревом поиска. Желательно представить решение на языке С++ или С. Оцениваются временная и пространственная сложность алгоритма, а так же универсальность подхода.


Ответ

UPD: моя неправда, исправляю. Предположим, что дерево определено так: struct BinaryTreeNode { BinaryTreeNode(int val) : leftChild(NULL), rightChild(NULL), parent(NULL), value(val) {}
BinaryTreeNode * leftChild; BinaryTreeNode * rightChild; BinaryTreeNode * parent; int value; }; Тогда алгоритм проверки будет следующим: bool isBST(BinaryTreeNode * root) { return isBST_(root, 0, 0); }
bool isBST_(BinaryTreeNode * node, BinaryTreeNode * minParent, BinaryTreeNode * maxParent) { if (minParent && minParent->value >= node->value) return false; if (maxParent && maxParent->value <= node->value) return false; if (node->leftChild != 0 && !isBST_(node->leftChild, minParent, node)) return false; if (node->rightChild != 0 && !isBST_(node->rightChild, node, maxParent)) return false; return true; } Временная сложность O(n), где n — количество узлов в дереве. Пространственная сложность O(h), где h — глубина дерева.

Ассемблер в Linux

Доброго времени суток, уважаемые гуру! Возникла необходимость обучиться ассемблеру, а работать в Windows на старом хламе в универе не хочется, поэтому выбирают ноут с установленной Ubuntu 11.04. Подскажите пожалуйста какие пакеты мне необходимо установить для написания программ на ассеблере, а также как собирать и компилировать это проги из консоли? В дальнейшем планируется связать ассемблер с C++, что для этого нужно и какую литературу необходимо почитать?


Ответ

Вам нужны binutils. В них есть или as86/ld86, или gas (GNU Assembler). Особенностью ассемблера gas является использование AT&T синтаксиса. Т.е. это означает следующее: прямой порядок операндов (т.е. src, dst, а не наоборот, как на платформе Wintel); все инструкции ассемблера имеют суффикс, определяющий размер операндов. например, movb. Никаких ужасных конструкций вроде dword ptr как в TASM/MASM:-) другой (чем у MASM/TASM) формат адресации и многое другое С другой стороны, этот синтаксис приближен к синтаксису ассемблера на нормальных, "больших" машинах. В gcc, кстати, говоря используется именно AT&T синтаксис ассемблера, так что очень рекомендую его изучить.

Сумма цифр натурального числа

Имеется натуральное число n. Например, оно вводится с клавиатуры вот так:
Scanner scanner = new Scanner(System.in); int n = scanner.nextInt();
Как я могу получить сумму цифр этого числа?
int sumDigits = ??? System.out.println(sumDigits);


Ответ

вроде как, должно быть так:
while(n != 0){ //Суммирование цифр числа sum += (n % 10); n/=10; } System.out.println(sum + " ");

Фреймворк для браузерной игры

Сейчас один достаточно компетентный человек сказал мне, что браузерную игру лучше всего делать без фреймворка, т.к. тогда достигается наибольшая скорость, а фреймворки (даже самые быстрые) тянут с собой слишком много для таких проектов, в т.ч. роутинг тратит слишком много ресурсов. Подскажите, стоит ли делать браузерку на основе фреймворка (я присмотрел CodeIgniter), или лучше с нуля?


Ответ

Если есть время, напишите с нуля. Получите опыт и на ошибках поймете что и как. А потом уже можно и на фреймворке.

Безопасность php кода [дубликат]

На данный вопрос уже ответили: Книги и учебные ресурсы по PHP 1 ответ Здравствуйте! Посоветуйте книгу или учебник или цикл статей, которые надо прочитать и освоить, чтобы проект был сделан максимально безопасным. Чтобы там были описаны основные уязвимости и как их избежать. Подробное руководство настройки и оптимизации php.ini Советы и рекомендации.


Ответ

Думаю такой книги нет,но вы можете почитать про все уязвимости

Считать строку неизвестной длины из файла

Есть файл, в нём записана строка неизвестной длинны, как мне её записать в массив char? Я что-то пытался, но ничего не вышло.
Вот убрал лишнее из кода, насчет двойного указателя не уверен.
char **str; //вот сюда надо записать из файла char ch; FILE *fp;
if ((fp = fopen("test.txt","r"))==NULL) { printf("File not found.
"); }
do { ch = getc(fp);//read
//тут видимо должен быть чудо-код
} while(ch!=EOF);
fclose(fp);


Ответ

Примерно так #include #include
int main() { FILE* f = fopen("file.txt", "r"); unsigned int N = 10, delta=10, i = 0; char* buf = (char*) malloc (sizeof(char)*N); while ((buf [i] = fgetc(f)) != EOF ) { if (++i >= N) { N += delta; buf = (char*) realloc (buf, sizeof(char)*N); } } fclose(f); buf[i] = '\0'; puts (buf); free (buf); return 0; }

Как угадать следующий AUTO INCREMENT (ID)?

Перед тем как добавить в базу, нужно узнать следующий ID который AUTOINCREMENT
Сделал так:
SELECT MAX(id) as maxid FROM tab0
$my_new_id = $db['maxid'] + 1;
Строки удалять не собираюсь DELETE, удаляю только UPDATE колонку show перевожу из true в false. Читал, что так делать нельзя ни в коем случае. Но не могу придумать другой реализации, а перерабатывать структуру не хотелось бы.
Какие подводные камни этой реализации, если не использовать DELETE? В каких ещё моментах может "сбойнуть"?


Ответ

LAST_INSERT_ID() // получишь последний ID last_insert_id()