Страницы

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

вторник, 2 октября 2018 г.

Как сделать прозрачный текст?

Мне нужно чтобы была кнопка, в которой текст был как фон (т.е. просто "дырявил блок")


Ответ

Две SVG кнопки с прозрачным текстом.
Анимация начинается при наведении курсора на цветные полоски слева. Прозрачный текст кнопок реализован при помощи SVG маски.
body { background-image: url(https://i.stack.imgur.com/AZ8Hg.jpg); background-repeat: no-repeat; background-size: cover; font-family: verdana, sans-serif; }

Button- Button+

Откуда C/C++ знает сколько надо освободить памяти, если не знает размер массива?

В C/C++ для того чтобы обработать массив нужно знать его размер. Соответственно нужно всегда этот размер "помнить" и протаскивать во все функции обработки в качестве аргумента. Например:
void foo(int* arr, size_t n) { for (size_t i = 0; i < n; i++) { arr[i] = i * i; } }
Но при освобождении ресурсов знать размер почему-то необязательно. Можно просто вызвать free(arr) если память выделялась через malloc() или calloc(). Или можно использовать оператор delete[] arr; если память выделялась через оператор new int[n]
Вопрос откуда C/C++ знает сколько надо освободить памяти, если не знает размер массива? Функция free() и оператор delete[] не принимают в качестве аргументов размер массива, а только указатель на массив. А если C/C++ может каким-то образом вычислить размер, то зачем его постоянно "таскать" с собой в отдельной переменной?


Ответ

Все это - детали реализации.
В популярных реализациях malloc обычно записывает размер выделенного блока в начало выделенного блока. Возвращенный вам указатель обычно указывает на память сразу за этим записанным размером. free знает, где искать размер блока, и извлекает его именно оттуда.
По умолчанию new и delete просто делегируют запросы на выделение и освобождение сырой памяти в тот же самый malloc и free или их аналоги, через посредство operator new и operator delete.
При работе с массивами объектов с тривиальными деструкторами new[] и delete[] фактически ведут себя точно так же: вызывают в конечном итоге malloc с правильно вычисленным общим размером массива и вызывают free для освобождения памяти.
При работе с массивами объектов с нетривиальными деструкторами все несколько сложнее: new[] дополнительно записывает в начало блока памяти точное количество элементов создаваемого массива, а delete[] потом извлекает это количество и вызывает правильное количество деструкторов.
Допустим, если у вас есть какой-то класс MyNonTrivialClass размером в 9 байт с нетривиальным деструктором, то выполнение
MyNonTrivialClass *p = new MyNonTrivialClass[17];
приведет к формированию блока памяти со следующей внутренней структурой
+-----+-----+------+------+------ | 176 | 17 | p[0] | p[1] | ... +-----+-----+------+------+------ ^ ^ ^ | | | | | p - полученный вами указатель | | | поле типа `size_t` (8 байт), записано `new[]` | поле типа `size_t` (8 байт), записано `malloc` `new[]` запросил 161 байт = 17 * 9 + 8, размер выровнен до границы 16 байт
Конкретные значения могут отличаться, но общая идея обычно в популярных реализациях именно такая.
См. также https://ru.stackoverflow.com/a/770300/182825

Безопасно ли сравнение == для типа double?

double d = -1;
if (d==-1) { }
При каких обстоятельствах, безопасность сравнения на == становится низкой? Надо переменную умножить, поделить или что, чтобы double начал показывать погрешность вроде не 0, а 0.00000001, и приходится применять эпсилон, а не простое сравнение. В настройках компилятора есть опция: Модель вычислений с плавающий точкой (точный, строгий, быстрый). На что она влияет, если установлено "быстрый", то double будет не точно работать?


Ответ

Отвечаю по-пунктам:
Нельзя сравнивать два числа с плавующей запятой между собой, из за того, что числа с плавующей запятой не могут быть представлены точно, по-этому мы не можем полагаться на оператор сравнения.
Популярная практика сравнения такая:
#include #include
bool is_equal(double x, double y) { return std::fabs(x - y) < std::numeric_limits::epsilon(); }
Можно задавать свой "эпсилон". Как я понял, речь идет о MS VC++. Опции компилятора описаны тут https://msdn.microsoft.com/ru-ru/library/e7s85ffb.aspx Если выбрать fast, то не будет соблюдаться стандарт IEEE 754. Не будут работать сравнения с Nan и пр.

Микросервисная архитектура Java

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


Ответ

Стоит добавить, что поскольку каждый каноничный микросервис -- это отдельный процесс, то теоретически для взаимодействия сервисов может использоваться что угодно из списка вариантов межпроцессорного взаимодействия. И хотя большинство способов взаимодействия сводятся к HTTP и очереди сообщений, сервисы могут "взаимодействовать" хоть через файловую систему. Например, может существовать сервис, который мониторит таблицу БД и выполняет определенную задачу с новыми/обновленными записями.

получается суть микросервисной архитектуре - это создание множества rest-сервисов, каждый из которых выполняет только одну конкретную задачу?
Во-первых, просто сервисов. REST -- это уже деталь имплементации. К тому же, у сервиса вообще может не быть никакого API. Во-вторых, создание множества сервисов -- это, конечно же, способ достижения цели. А суть микросервисной архитектуры заключается в следовании принципу единой обязанности. И уже отсюда вытекает все остальное: способы реализации, плюсы и минусы.

Что нужно знать для практического использования С++?

Допустим, я изучил с++. Однако это всего лишь консольные приложения, классы, ссылки, указатели, работа с файлами и т.д.
Как писать драйвера? (в какую сторону смотреть, есть ли книги или документация). Что вообще следует писать на с++ и "как, чем"? Какой API лучше использовать для написания оконных приложений и стоит ли это делать на с++?
Вот я и не могу понять, как это происходит, ведь в книгах с++ этого нет. Надеюсь вы поняли ход моих мыслей и сможете прояснить. Спасибо.


Ответ

На мой взгляд одна из самых актуальных проблем современной литературы - много фундаментального и мало более профессионального. Я постараюсь объяснить это так, как вижу сам. Хотя знаний у меня не так уж много, но по крайней мере я попытаюсь. Надеюсь знающие люди подправят, если ошибся. Итак, работа электроники происходит посредственном передачи данных по шинам от одного управляющего устройства другому(процессоры, микропроцессоры, микроконтроллеры и т.д.). В зависимости от того, какие данные переданы, электроника выполняет определенные задачи. Фактически это уровень архитектуры компьютера и ассемблера, которую очень хорошо бы знать на базовом уровне(Тоненбаум - "Архитектура компьютера"). Команды эти обычно объединяются в своего рода блоки, аналогично функциям, которые делают какую-то определенную цель. Иногда создаются целые кучи функций, которые объединяются в библиотеки функций(те самые math, iostream и т.д.). Низкий уровень, драйвера: Для написания драйвером надо посылать эти самые команды управляющим устройствам. Язык С++ не очень подходит под эти задачи, проще пользоваться чистым Си. В самом простом случае подключается какая-то библиотека, которая позволяет посылать значения устройствам и читать их. К примеру, простейший способ обращения к динамику ПК может выглядеть так(учтите, windows не разрешает напрямую обращаться к портам!): #include main( ) { int store; store = inp (97); /* запоминание начального значения с помощью порта 97 */ printf("пopт 97 = %d
", store); /* проверка результатов*/ outp(97, 79); /* посылает 79 в порт 97; включение громкоговорителя */ outp(97, store); /* восстановление начального значения */ } Правда добрые люди обычно делают сторонние библиотеки более высокого уровня, которые уже содержат список готовых функций, классов, структур для обращения к устройствам. Например, код выше прекрасно работает из библиотеки функций windows.h, вызывая функцию beep(). Если вы хотите писать драйвера, то вам придется читать о том, как обращаться к устройству из документации разработчиков с оффициальных сайтов, какие команды устройство может выполнять, какие данные надо для этого посылать, есть ли для этого специальные библиотеки от разработчиков и многое другое. Высокий уровень. Люди, которые используют С++, работают обычно с готовыми наборами библиотек или создают свои под те или иные задачи. Например, есть такая вещь как WinAPI для создания графического интерфейса Windows окон. Это опять же готовые функции, вы подключаете библиотеку и работаете с ними. В ответ они делают какую-то работу и выдают результат. Если вы посмотрите на минимальное окно, то в коде вы увидите заполнение знакомых элементов: структуры, вызов функций, использование циклов и т.д. Другое дело, что эти функции и структуры сделали разработчики и они выполняют определенную работу, Вам остается только их вызывать. Для ознакомления с ними есть документация. Все выше и выше. Обычно библиотеки делаются универсальными и их можно использовать повторно. Например, на основе одной можно создать другую которая будет выполнять еще более специализированные функции. Например, можно создать библиотеку с функцией рисования линий. Из нее библиотеку с функцией рисования геометрических фигур. Из нее библиотеку с рисование деталей и т.д. так наращивается функциональность. Есть например программное рисование графики на мониторе, в windows его надстройка winAPI(линии, окошки, цвета уже готовы), но и у него есть более высокоуровневая оболочка MFC или Windows Forms, которые являются более усовершенствованными, но основаными на все том же WinAPI. Как итог: фактически работа программиста заключается в том, что бы выяснить какая библиотека может помочь справиться с нужными задачи и изучить ее. А изучив применить к своим нуждам. Хотите использовать Windows GUI приложения - есть WPF и Windows Form, или на более низком уровне взять WinApi. Хотите использовать видеокарту для 3D приложений - изучайте DirectX. Хотите работать с музыкой, опять же всякие библиотеки типа OpenAL есть в распоряжение. Охота писать драйвера, ищите информацию о том, как можно обращаться к устройствам и посредством какой библиотеки. Хотите узнать почему используются готовые библиотеки, изучите архитектуру компьютера и самые основы ассемблера. В любом случае вы будете пользоваться основными изученными элементами языка С++: структуры, функции, классы, указатели, простые типы данных и т.д. P.S. Пока писал, уже засомневался в правильности написанного)) Советую еще посмотреть вот этот сайт: http://www.firststeps.ru/

Как mutex определяет, какой именно объект нужно блокировать?

Как известно,
Задача мьютекса — защита объекта от доступа к нему других потоков, отличных от того, который завладел мьютексом. В каждый конкретный момент только один поток может владеть объектом, защищённым мьютексом. Если другому потоку будет нужен доступ к переменной, защищённой мьютексом, то этот поток блокируется до тех пор, пока мьютекс не будет освобождён.
Но как мьютекс определяет, доступ к какому именно ресурсу/объекту/переменной нужно блокировать? Ведь в него не передается никаких параметров, из которых он мог бы знать что именно защищать.
Если что, речь о std::mutex, с++11.


Ответ

Дополню ответ @alexis031182.
Мьютекс или семафор, как его обобщение (конкретно, объект (переменная), расположенный по некоторому адресу) это точка синхронизации потоков кода одного или (в некоторых случаях) нескольких процессов.
И ничего более. Он ничего не защищает. Ни объекты в памяти, ни участки кода. Поток не вызывающий операцию lock с этим мьютексом может делать что хочет с любыми переменными и участками кода. Защита производится на логическом уровне (в голове разработчика).
Фактически поток кода, вызвавший операцию lock для указанного мьютекса увеличивает счетчик, связанный с этим мьютексом и продолжает выполнение если счетчик был равен нулю.
В противном случае этот поток ожидает, пока счетчик не станет равен 0 (тогда он в свою очередь увеличит его и продолжит выполняться), что произойдет, когда кто-то вызовет unlock, уменьшающий счетчик на 1.

Знак ! в арифметических выражениях, зачем он?

Смотрел я как то, не так давно, почти что только что, код своего преподавателя, набирался уму - разуму, да попивал чай зеленый с коньячком, и вдруг встречаю я странную штуку: k=k+!(k%2); Углубился я в раздумья - "встречал то раньше я знак восхищения только в логических выражениях, а тут вот на тебе"... И как бы я часто клавишу F10 не нажимал так понять и не смог, зачем оно и что делает. Помню, как то, человек хороший, сказал мне мудрость вот такую, что напиши ты int a=0; a следом сразу a=~a; то а в мгновенья станет -1, так вот, возможноль, что и этот случай, который был описан выше, причастен к фокусам из этих серий?


Ответ

Да, это из той же серии, что и ~a
На самом деле !a эквивалентно (a == 0) и имеет тип bool. Но когда вы интерпретируете это значение как int (а у вас так и происходит, из-за сложения с целым), bool превращается в 0 или 1. Таким образом, как целое число наше выражение эквивалентно a == 0 ? 1 : 0. В частности, если известно, что a -- 0 или 1, то это просто меняет значение на противоположное: если был ноль, станет 1, иначе станет 0.
Таким образом, выражение k+!(k%2) следует понимать так:
если k было чётным, k%2 == 0, ! обращает значение в 1, и в результате получается k+1 если k было нечётным, k%2 != 0, ! обращает значение в 0, и в результате получается просто k
То есть результат -- ближайшее (сверху) нечётное число. Makes sense?

Такая техника, как в вашем примере -- один из примеров кода, за который одни обожают, а другие ненавидят язык С++ (и С). Специалисты, тяготеющие к С, обычно больше любят такую лаконичную запись, а те, кто видит в языке скорее высокоуровневые конструкции, чем биты и байты, часто морщатся от такого кода. Я отношу себя к любителям высокоуровневых языков, но мне такие лаконичные конструкции нравятся.

Вот тут собрано много примеров подобного кода. Почитайте! Ещё несколько мозгоразрывающих примеров на SO: здесь и здесь

(Вынес из комментариев) Кстати, обратите внимание, что более коротким (и возможно более эффективным) кодом, выполняющим ту же задачу, является
k |= 1;
Он, кстати, работает и для отрицательных значений k (это не вполне очевидно).

Кастование числа к строке не кидает ClassCastExeption при использовании дженериков - почему?

Объясните, пожалуйста, почему в строчке //(?!) не выбрасывается исключение ClassCastExeption? Там стоит (T), где T=String, а значит там (String) new Integer(42), что должно давать исключение... JVM должна привести тип, но почему-то она этого не делает. Дальше мы смотрим тип t и видим Integer, что действительно является реальным типом t. Но факт того, что мы вывели тип, показывает: исключение не создалось. Потом программа выбрасывает исключение там, где была вызвана функция A.f()
Кстати! Помнится мне, Bruce Eckel учит тому, что существует некоторый декомпилятор javap, он сам пишет код программы то ли из байт-кода, то ли из .class... Не изучал. Если кто сведущ в этом, попробуйте заставить декомпилятор построить этот кусок кода, может он покажет, что там происходит на самом деле, и почему?
public class A { public static T f() { T t = (T) new Integer(42); // (?!) ЧТО ЧЁРТ ВОЗЬМИ ЗДЕСЬ ВООБЩЕ ПРОИСХОДИТ?! System.out.println(t.getClass()); return t; }
public static void main(String[] args) { System.out.println(A.f()); // как здесь возможно исключение? ахаха, вы серьёзно? } }
Новое: Итак, друзья. Самым частым ответом стало: метод f() -- это обычный метод, который компильнулся как обычный, но с учётом того, что результаты его вызовов приводятся к типу, передаваемому как . Вроде бы уже всё хорошо, и можно принять такой ответ, но если бы оно правда так работало в Java... Дело в том, что можно в main(String[]) попытаться вызвать кое что ещё более взрывное:
System.out.println(A.f());
Удивительно, но в консоли выйдет:
//output: class java.lang.Integer 42
Так вот если у нас невидимо это выглядит так:
System.out.println((Double)A.f());
То попробуйте это компильнуть -- выйдет ошибка ахахахха, от куда вывод, что всё таки работает оно не так...
Мои догадки на этот счёт таковы, что метод println() перегружен, и в случае A.f() он выбирал версию println(String arg), а в случае A.f() он понимал, что Double версии нет и ставил println(Object arg) из-за чего, для нашего (Object)Integer(42) вызывалось .toString() и выводилось 42.
Для меня здесь странно то, что почему-то в первом случае, когда мы вызывали A.f() он, как многие здесь считают вызывал это так (String)A.f(), от куда ставил версию println(String arg), а во второй раз, при вызове A.f() он не попытался сделать так (Double)A.f(), он сразу выбрал println(Object arg)...
Хотите сказать, что вся технология такая умная, что если возврат параметризованной/обобщённой функции проверяется на существование как аргумент в перегруженном методе println() с успехом, то приведение не вызывается [например String версия println() существует, ага, приведём выходной Object от A.f() к указанному String], а если перегруженной версии с указанным в типе-параметре для A.f() классом версии println() нет, то он (компилятор) оставляет версию println(Object) и решает не пытаться даже сделать (Object)(Double)A.f(), где сам результат f() есть Object ?
Итого: Я хочу объяснения принципа работы параметризованных методов (классов), такое объяснение, чтобы был точно понятен алгоритм действий компилятора для создаваемого кода. Если какие-то мои догадки на счёт действий компилятора верны, то я хочу их (моих догадок) подтверждения и очень желательно (!) с ссылкой на какие-нибудь документационные файлы!


Ответ

Это байткод main при вызове A.f()
public static void main(java.lang.String[]); Code: 0: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream; 3: invokestatic #7 // Method f:()Ljava/lang/Object; 6: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 9: return
А это байткод main при вызове A.f()
public static void main(java.lang.String[]); Code: 0: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream; 3: invokestatic #7 // Method f:()Ljava/lang/Object; 6: checkcast #8 // class java/lang/String 9: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 12: return
Обратите внимание на строку invokevirtual, в первом случае вызывается метод с сигнатурой println(Object o), во втором - println(String s) В случае с Double после стирания типов метод f() возвращает Object, метода println для Double нету (да, можно анбоксить Double и вызвать println для примитива double, но приоритет отдаётся выбору подходящего метода), поэтому выбирается метод для Object, внутри спокойно вызывается String.valueOf и всё хорошо. В случае со String есть метод println для String и компилятор решает, что нужно вызывать именно его, поэтому там есть каст.
Я обернул System.out.println в свой println для 3 типов:
static void println(Double d){ System.out.println(String.valueOf(d)); }
static void println(String s){ System.out.println(String.valueOf(s)); }
static void println(Object o){ System.out.println(String.valueOf(o)); }
И теперь вы уже догадались что будет при вызове?
public static void main(String[] args) { println(Main.f()); }
Компилятор увидит, что есть перегруженный println для Double и поставит каст (и тут как раз ошибка будет):
public static void main(java.lang.String[]); Code: 0: invokestatic #7 // Method f:()Ljava/lang/Object; 3: checkcast #8 // class java/lang/Double 6: invokestatic #9 // Method println:(Ljava/lang/Double;)V 9: return

Как сделать, чтобы nodeJs сервер работал без активированной консоли?

Дали пробную неделю на VPS хостинг, поставил там NodeJS, но проблема в том, что он работает, только тогда, когда активирована консоль. Как сделать, чтобы он работал бесконечно?


Ответ

С момента последнего ответа прошло уже три года. Node.js существенно "повзрослел" за это время, так что вопрос не потерял своей актуальности.
Думаю стоит упомянуть еще несколько вариантов, которые отсутствуют в других ответах.
Forever
В экосистеме Node.js существует пакет forever. Его можно использовать как порождающего демона для вашего приложения. Из плюсов этого решения можно отметить простоту и возможность не писать дополнительный код. Кроме того, можно настроить forever так, чтобы он автоматически перезапускал приложение при его падении. Из минусов -- необходимость тащить в систему node.js скрипт-демон, который нужно устанавливать глобально. В ряде случаев это может оказаться неприемлемым. Запуск приложения, с использованием этого решения выглядит так:
forever start app.js
а его остановка:
forever stop app.js
PM2
Другим популярным решением из экосистемы Node.js является менеджер процессов PM2. Как и в случае с forever, pm2 это глобальный установленный node.js процесс-демон (со всеми плюсами и минусами). После его установки запуск приложения осуществляется командой:
pm2 start app.js
а его остановка:
pm2 stop app.js
init.d
Можно написать обычный init.d скрипт для вашего приложения. Этот путь используют все нормальные службы Linux. Если говорить о плюсах этого решения, то ваше приложение будет запускаться и останавливаться самой системой, нет необходимости устанавливать лишний процесс демон. Из минусов -- вам перезапускать приложение при падении в ручную (или с помощью специальных утилит). Так же вам придется написать сам init.d скрипт. За основу можно взять, например, вот это решение. Запуск приложения, с использованием этого решения выглядит так
service app-service-name start
а его остановка
service app-service-name stop

Код из звёздочек

Как использовать это в качестве кода?
** ***** ** ** ** ** ** ** ** **** ** ** ** ** *** ** ** ** ******************** *********************
Приветствуются оригинальные решения. Вариант с наибольшим числом голосов побеждает.
function getAnswers(questionId, answer_filter, page) { return jQuery.ajax({ url: '//api.stackexchange.com/2.2/questions/' + questionId + '/answers?page=' + page + '&pagesize=100&order=desc&sort=activity&site=ru.stackoverflow&filter=' + answer_filter, method: "get", dataType: "jsonp", crossDomain: true }).then(function(data) { if (data.has_more) { return getAnswers(questionId, answer_filter, page + 1).then(function(d) { return data.items.concat(d.items); }) } return data.items; }); } function getAuthorName(e) { return e.owner.display_name } function process(items) { return items.map(function(item) { var matched = item.body.match(/\s*(.+?)\s*<\/h/); if (matched) { return { lang: matched[1], count: item.score, link: item.share_link, author: getAuthorName(item) }; } else { return { lang: "N/A", count: "N/A", link: item.share_link, author: getAuthorName(item) } } }); } function sort(items) { return items.sort(function(a, b) { return b.count - a.count; }) } function fillTemplate(sortedItems) { $('#leadership').append(sortedItems.map(function(item, index) { return $('').append($('').html(index + 1)) .append($('').html(item.author)) .append($('').html(item.lang)) .append($('').html(item.count)) .append($('').append($('').attr('href', item.link).text('Link'))); })); return sortedItems; } var QUESTION_ID = 520257, ANSWER_FILTER = "!4*SyY(4Kifo3Mz*lT", startPage = 1; getAnswers(QUESTION_ID, ANSWER_FILTER, startPage) .then(process) .then(sort) .then(fillTemplate); #leadership { border-collapse: collapse; } #leadership td, #leadership th { padding: 5px; } #leadership th { text-align: center; }

Таблица лидеров

Автор Язык Счет


Ответ

C++
http://ideone.com/JRY307
struct outputter { outputter operator*(); };
int main(int argc, char* argv[]) { outputter o;
** ***** ** ** ** ** ** ** ** **** ** ** ** ** *** ** ** ** ******************** *********************
o;
return 0; }
#include #include #include #include
using namespace std;
string text = "IF you happen to have read another book about Christopher Robin, " "you may remember that he once had a swan (or the swan had Christopher " "Robin, I don't know which) and that he used to call this swan Pooh. " "That was a long time ago, and when we said good-bye, we took the name " "with us, as we didn't think the swan would want it any more. " "Well, when Edward Bear said that he would like an exciting name all to himself, " "Christopher Robin said at once, without stopping to think, that he was " "Winnie-the-Pooh.";
istringstream iss{ text }; auto it = istream_iterator{ iss };
outputter outputter::operator*() { cout << *it++ << " "; return *this; }

Идея: объявим класс с оператором *, который будет возвращать сам объект. Таки образом, можно вызывать оператор * сколько угодно раз подряд.
Чтобы объект делал что-нибудь полезное, возьмём текст из Винни-Пуха (string text = ...), положим его в поток iss, и будем читать из потока итератором (istream_iterator) (потоковое чтение строки читает одно слово за раз, так же, как и с cin, поэтому мы фактически разбили текст на слова по пробелам). Каждый раз во время работы оператора * выведем следующее слово и продвинем итератор.

Цикл на ассемблере

Пусть A и B – два 8-разрядных регистра в обыкновенном 16-разрядном процессоре. Следующая процедура выполняет сдвиг регистра A на число разрядов, заданное в регистре B. Loop: SHR A ;shift right A DEC B ;decrement B JNZ Loop ;loop again Задача - Написать программу, которая выполняет сдвиг быстрее. Пользоваться многократным сдвигом запрещено. ЗЫ Эту задачу когда-то мне предложили на собеседовании. Я ее решил не верно. У кого какие мысли? Гугл не поможет :) Надо думать самому! UPD: Нашел свое неверное решение MOV AH,A MOV AL,B Label: SHR AH DEC AL JNE Label


Ответ

И третий вариант:) Предложен моим коллегой. Развернуть цикл. jmp $+sizeof(shr a)*(8-b) // $ - это адрес следующей за jmp инструкции shr a shr a shr a shr a shr a shr a shr a shr a

Приложение для устройства на первую работу [закрыт]

Доброго времени суток. Ситуация такая, собираюсь устраиваться на junior .NET разработчика, это будет первая работа. Хочу написать какое-то осмысленное и более-менее полезное приложение (или даже два), выложить на гитхаб и добавить ссылку в резюме. Считаю, что это увелит шансы попасть на работу, т.к. работодатель увидит хоть какой-то реальный код, ну или как минимум увеличит шансы попасть на собеседование. Собственно я хочу, чтобы вы предложили идею такого приложения, оно должно быть не очень сложным, уровня джуниора. Приложение будет десктопным, писаться будет на WinForms или WPF. Сам вот пока ничего интересного не придумал, кроме банальных органайзеров или менеджеров задач ничего в голову пока не пришло. Может вы посоветуете?


Ответ

Клиент для hashcode.ru (с треем и оповещениями о новых темах) Скриншотер (для снятия скриншотов с экрана) игру "Жизнь" Конвея (она простенькая совсем) Это то, что первое в голову пришло. Может потом дополню еще...

Как нарисовать автомобиль с помощью команд SVG

Ниже изображение автомобиля в формате png Я хочу сделать анимацию движения автомобиля вдоль какой-нибудь траектории. Желательно, чтобы колёса автомобиля вращались. Я понимаю, что для этого необходимо перевести картинку в формат svg Как это сделать? С помощью векторного редактора или вручную, используя формулы svg, или, как-то по другому, например: применяя трансформации css3


Ответ

Движение автобуса по заданной траектории:
* { margin: 0; padding: 0; } line { stroke-width: 3px; stroke: #bf0208; } Lorem Bus Lorem Bus

Как мне улучшать свою программу без потери того что я уже сделал

У меня есть программа, она работает, но теперь я хочу её улучшить. Но возможно такое что при попытке её улучшить, она перестанет работать, и я не смогу вернуться к тому что было в начале. Чтобы сохранить рабочую версию мне каждый раз нужно делать копию проекта или есть что-нибудь попроще?


Ответ

Использовать TFS или Git. Применять для улучшений ветвление исходного кода Можно так же использовать и ваш метод с копированием, но это анахронизм.

Вы выросли из разработчика в бизнесмена? [закрыт]

Есть такой опыт, и если есть, то расскажите вашу success или fail историю :)


Ответ

У меня знакомы вырос. Это мой бывший работодатель. Окончил иняз, обучился САМ программированию. Напсал свою CMS - создал фирму и сейчас делает сайты (они из лучших в нашем городе).

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

Пытаюсь сам реализовать безразмерный саморасширяемый массив, вначале на 2Gb, затем больше. Т.е. при обращении к элементу массива чтобы проверялось, есть ли кластер в оперативке, и выдавался кластер, если нет - чтобы кластер грузился из файла. Если кластеров много - менее используемые выгружались. Т.е. как некая неисчерпаемая виртуальная память. Цель - закешировать результат выборки из любой СУБД, например, если она вернула миллион строк.
Может, есть готовая библиотека реализующая это через IStream интерфейс работы с файлами, или что-то такое? Часть СУБД бывают 32bit, чтобы решение могло работать и в 32bit, и 64bit. VirtualAlloc не подходит (адресное пространство в 32bit ограничено).
В идеале нечто такое
class BigArea{
operator char& [] (__int64 index) { char * tmp_buff; //... return &tmp_buff[ index & 4095]; // Т.к. блок памяти 4096 байт. } }
Как источник "неисчерпаемой" памяти. Есть ли библиотека, которая позволит закешировать 2-4-10 Gb памяти, разместив "лишнее" на диске, а наиболее используемую память в оперативной памяти?


Ответ

Поскольку реализации до сих пор нету, собрал такой "скелет".
class TBigMem{ private: HANDLE hFile; HANDLE hMap; __int64 hIndex; //можно переназначить тип на тот, который в вашей IDE __int64 maxsize; void * mWnd; DWORD AllocationGranularity; // Размер кратным которого должно быть окно
bool DoMap(unsigned long * index){ if (hIndex >=0) UnmapViewOfFile(mWnd); hIndex = *(__int64*)index; void * wnd = MapViewOfFileEx(hMap, FILE_MAP_ALL_ACCESS, index[1], index[0],AllocationGranularity,mWnd); /*Окно*/ if (wnd == 0) wnd=MapViewOfFileEx(hMap,FILE_MAP_ALL_ACCESS, index[1], index[0],AllocationGranularity,NULL);/*Новое окно*/ if (wnd == 0) { /*Обработать ошибку - не хватает памяти скорее всего*/}; if (wnd!=0) mWnd = wnd; return wnd != 0; };

public: TBigMem (__int64 size) {// Размер можно сделать константой char buff[512]; SYSTEM_INFO si; GetSystemInfo(&si); AllocationGranularity = si.dwAllocationGranularity; GetTempPathA(sizeof(buff),buff); GetTempFileNameA(buff,"bigmem",0,buff); // Тут задать префикс для временного файла hFile = CreateFileA(buff,GENERIC_READ | GENERIC_WRITE ,0,NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,0); hIndex = -1; Realloc(size); }
bool Realloc(__int64 size){ if (!hFile) return 0; if (hIndex >=0) UnmapViewOfFile(mWnd); if (hMap) CloseHandle(hMap); hMap = 0; hIndex = -1; hMap = CreateFileMappingA(hFile,0, PAGE_READWRITE, ((unsigned long*)&size)[1], ((unsigned long*)&size)[0] ,0); if (hMap !=0) maxsize = size; return hMap != 0; }
bool isValid() { return hMap !=0; };
~TBigMem(){ CloseHandle(hMap); CloseHandle(hFile); };
char& operator[](__int64 index){ union { __int64 i; unsigned long w[2]; } u; if (index >= maxsize)// Авторасширение с выравниванием Relloc(index - (index & AllocationGranularity)+AllocationGranularity); if (hMap == 0) return *(char*)NULL; // Не возможно, обработать ошибку unsigned long offs; int err = 0; u.i = index; offs = u.w[0] & (AllocationGranularity-1); u.w[0] &= ~(AllocationGranularity-1); //TODO: тут можно дописать сдвиг индекса, что б окно было шире if (u.i != hIndex) DoMap(&u.w[0]); //err = GetLastError(); return *((char*)mWnd + offs); };
unsigned int GetAvalible(__int64 index) { // Колличество байт, доступных в окне return AllocationGranularity-((unsigned int)(index & (AllocationGranularity-1))); } };
Протестировал на небольших обьёмах так:
char c; TBigMem data(1000000); data[0]=1; data[65536]=2; с = data[0]; // переключить на первую страницу с = data[65536]; // переключить другую станицу
Данные сохраняются. Пришлось разобраться с тем, как делать мапинг, с грануляцией страниц, с переключением отображения (во многих примерах переключения страниц отсутствует).
P.S. Ожидаю более удобную реализацию. На сейчас момент это единственный пример реализации.
Для char такое решение подходит, а для более емких типов нужно добавить "двойной" буфер, потому что при размере более одного байта тип может оказаться на "разрезе двух страниц". Я столкнулся с тем, что не нашёл толкового описания как зарезервировать память для MapViewOfFileEx. Для "расширеного" функционала, возможно нужны шаблоны template, это на будущее.

JIT optimization

Приветствую, уважаемые!
На днях занимался оптимизацией своего кода и пришел к выводу, что оптимизация VS сломала все мои понятия о "правильном" коде. Чисто случайно наткнулся на забавную вещь:
double res = (int)Math.Round(1.4);
.NET 4.5, в релизе, x86, со включенной оптимизацией работает в 1.5 раза быстрее, чем
double res = Math.Round(1.4);
Я сразу полез в дизассемблированный код, и наткнулся на строки, из-за которых и пишу вам:
double res = (int)Math.Round(1.4); 004E2643 sub esp,0Ch 004E2646 fld qword ptr ds:[4E2678h] 004E264C fistp dword ptr [ebp-0Ch] 004E264F mov eax,dword ptr [ebp-0Ch] 004E2652 mov dword ptr [ebp-0Ch],eax 004E2655 fild dword ptr [ebp-0Ch]
Два дня ломаю мозг, не могу понять, что делают в данном случае команды mov? Может у вас есть идеи?
По просьбам, добавлю:
double res = Math.Round(1.4); 00432646 fld qword ptr ds:[432670h] 0043264C frndint


Ответ

про firstp я нашел вот что
Различные ошибки в этой команде могут встречаться на процессорах Pentium. В процессоре Pentium III существуют некоторые ситуации, когда команды FST, FSTP, FIST и FISTP с операндом в памяти не генерируют исключения #P несмотря на проблемы с точностью. Обратитесь к технической документации Intel за описанием всех возможных случаев проявления ошибки. Для однозначного устранения всех предпосылок возникновения этой ошибки используется две команды NOP перед критической командой FPU.
У вас после fistp через те самые 2 mov которые ничего вроде не делают идет fild. Можно ли ее принять за критическую команду FPU? Скорее да чем нет, а может закладка на все случаи жизни.
Так что я бы сказал эти 2 mov работают как упомянутые выше 2 NOP. А может даже лучше.

Когерентность кэша и Java Memory Model

Может ли когерентность кэша повлиять на работу многопоточного Java-приложения? Или все проблемы решает виртуальная машина? В каких случаях один и тот же многопоточный код будет работать по-разному в зависимости от кэш-памяти?


Ответ

По идее для объектов, отмеченных volatile когерентность должна обеспечиваться независимо от аппаратной поддержки когерентности кэшей. У большинства современных (SMP) компьютеров обеспечение когерентности кэша встроено в конструкцию. Этого нет (насколько мне известно) у HPC (high performance computing) кластеров. Знаю, что в реализации JVM для них обещают Truly portable threads and synchronization model. Вообще же, проблемы с параллельными потоками всегда на совести программиста.

Редкие, экзотические структуры данных и их применение? [закрыт]

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


Ответ

Динамический массив размером до 2^32 элементов с временем вставки O(1).
По сути структура MMU с динамическим выделением сегментов данных и блоков оглавления нижнего уровня. Оглавление всегда 2 уровня.
Года полтора назад здесь был вопрос Как реализовать динамический массив? в ходе ответа (скорее спора о возможности операций с такой структурой за время O(1)) появилась такая структура данных. Там и программка есть.
Применение неизвестно.

Доступ к комментариям HTML

Есть ли какая-то возможность взаимодействия с HTML комментариями посредствам JS?

простотекст
P.s. не надо говорить, что лучше использовать display:none. Мне просто чисто теоретически интересно именно взаимодейсвтие с комментами.


Ответ

Вот тут пример. jquery там не обязателен, так для мнимого удобства. С вашего позволения:

text3test
JS: $(document).ready(function(){ $("div").each(function(){
child = this.firstChild; while (child){
// determine the type of the node switch (child.nodeType){ // if the node is a comment node, output its value case Node.COMMENT_NODE : alert(child.nodeValue); break; }
// move to the next child node child = child.nextSibling;
} }); });

Для чего в Python 3.8 вводят новый оператор :=?

PEP 572 - Assignment Expressions вводит новый оператор :=
Что он делает? Для чего он нужен?


Ответ

Примеры из существующего (не специально придуманного) кода (grep-нул по диску), к которому можно PEP-572 применить:
копирование файлов (и аналогичный код для сокетов и других объектов, из которых можно данные принимать пока не пусто):
# copy the rest buf = inputfile.read(bufsize) while buf: outputfile.write(buf) buf = inputfile.read(bufsize)
с PEP-572 можно заменить на::
# copy the rest while buf := inputfile.read(bufsize): outputfile.write(buf)
что, конечно, и сейчас можно записать как:
# copy the rest shutil.copyfileobj(inputfile, outputfile, bufsize) копирование, где shutil.copyfileobj() нельзя напрямую применить (см. Get an audio file with HTTP GET and then play it in python 3. TTS in python 3?):
while True: data = wavfile.readframes(4096) if not data: break output_file.write(data)
с PEP-572 можно заменить на:
while data := wavfile.readframes(4096): output_file.write(data)
иногда это пишут через iter() c двумя аргументами (см. Floating point to 16 bit Twos Complement Binary, Python):
output_file.writelines(iter(lambda: wavfile.readframes(4096), b'')) ветвление с регулярными выражениями, к примеру, код из Python 3 get song name from internet radio stream
m = re.search(r"StreamTitle='([^']*)';", metadata) if m: title = m.group(1) if title: break # found title
можно заменить на:
if m := re.search(r"StreamTitle='([^']*)';", metadata) and title := m.group(1): break # found title списковое включение (listcomp), где какое-то выражение несколько раз используется. К примеру, чтобы напечатать публичные неспециальные свойства объекта obj (атрибуты-не методы) как словарь, созданный dictcomp:
pprint({name: attr for name in dir(obj) if not name.startswith("__") for attr in [getattr(obj, name)] if not callable(attr)})
здесь DRY реализуется с помощью: for attr in [getattr(obj, name)] идиомы (добавляется лишний вложенный цикл по списку из одного элемента). C PEP-572 это можно переписать как:
pprint({name: attr for name in dir(obj) if not name.startswith("__") and not callable(attr := getattr(obj, name))})
Конечно, особенно в тех случаях когда целое выражение не нужно, можно явный цикл использовать вместо dictcomp.
Ещё пример listcomp (см. Base RLE encode python):
def rle_groupby(text): return ''.join([char if count == 1 else str(count) + char for char, same in groupby(text) for count in [sum(1 for _ in same)]])
здесь та же DRY идиома используется со списком из одного элемента. C PEP-572 это можно переписать как:
def rle_groupby(text): return ''.join([char if (count := sum(1 for _ in same)) == 1 else str(count) + char for char, same in groupby(text)])
Примеры существующего кода и улучшенных вариантов из самой PEP-572
Q: Почему нельзя использовать обычный оператор =, как в C#?
A: Чтобы не было путаницы с == как в Си между if (x == y) и if (x = y), которые кардинально разные вещи делают.

Возможности для увеличения быстродействия многопоточных программ

Всем добрый день!
Назрел очередной вопрос для тех, кто занимается многопоточными программами: каким образом вы улучшаете показатели быстродействия программы, в случае, если она не оправдала возложенных на нее в этом плане ожиданий?
Опишу проблему подробнее. После перевода проекта под FreeBSD в многопоточный вариант, итоговая скорость работы не понравилась. Логика исходного проекта должна была остаться практически идентичной, и разнести данные по потокам так, чтобы, например, один поток работал только с одной структурой, и больше никуда не лез, не удалось. Соответственно, упор был сделан на "тонкую синхронизацию", - вышло множество блокировок и мьютексов, которые, теоретически, не должны захватываться кем-то надолго. Но теперь есть опасения, что наличие большого количества обращений к мьютексам выигрыш от использования многопоточки свело на нет. Поделитесь, пожалуйста, опытом, на что стоит обратить внимание, и есть ли какие-то еще возможности борьбы за скорость помимо полной переработки логики проекта?
UPDATE
Чтобы не было путаницы, опишу приближенную модель проекта. В рассматриваемой системе было 4 потока в расчете на 4 ядра:
1-й - основной поток, обслуживает новые соединения, обрабатывает прерывания, и выполняет несрочную работу во время простоя; 2-й - поток приема и обработки запросов от пользователей; 3-й и 4-й - потоки выполняющие обработку разных частей трафика.
Все потоки в недетерминированные относительно друг друга моменты времени периодически читают и записывают данные в различные структуры (порядка 10 штук, включают различные счетчики, массивы с индексами), а так же читают и редактируют 4 различных списка. Основной идеей многопоточного варианта программы было отделить пользователей от обработки трафика, чтобы в случае высокой загрузки они не ждали очень долго, а так же увеличить скорость обработки трафика.


Ответ

Имеющихся в вопросе данных, конечно, очень мало, но что могу добавить: При решении вопроса о количестве потоков стоит идти не от задач, а от объёма работ. Т.е. я очень подозреваю, что сейчас потоки 1 и 2 в основном простаивают. Так что лучше, например, сделать ещё по одному потоку, аналогичному 3 и 4, а возможно и по 2-3. Таким образом, если будет идти много трафика, обрабатываемого потоком типа 3, всем 4-м физическим ядрам будет, чем заняться. Учитывая, что при текущем разделении по типу работ, возникает большое количество взаимодействий, гораздо лучше сделать несколько однотипных потоков, которые будут выбирать задания из общей очереди и класть результаты в другую общую очередь. Естественно, остаётся задача выделения работы, которую можно выполнять с минимумом взаимодействий. Наверняка можно что-то найти, парсинг запроса какой-нибудь или тяжёлые расчёты. Есть ещё различные приёмы для уменьшения конфликтов по данным. Например, создание пула памяти отдельно для каждого потока, чтобы они не толкались при выделении памяти. Или, скажем, каждый поток может подсчитывать какую-то статистику (как раз счётчики) только по тому, что он обработал, а потом, изредка, эта информация может объединяться в главном потоке. Можно попробовать задать отдельный вопрос на эту тему

Создание экземпляра интерфейса

Недавно наткнулся на странный вид создания экземпляра интерфейса. Я знаю,что создавать экземпляры абстрактных классов и интерфейсов нельзя, но данная запись выглядит как-то странно.
Вопрос заключается в следующем: как можно охарактеризовать данную запись?
public class TestApp {
public static void main(String[] args) {
Animal animal = new Animal() { //? @Override public void say() { System.out.println("i am animal"); } };
}
public interface Animal {
void say();
}


Ответ

Это - конструкция создания экземпляра анонимного класса. Она создаёт класс, унаследованный от класса/интерфейса Animal. Экземпляры абстрактных классов и интерфейсов создавать, действительно, нельзя, но в данном случае анонимный класс (пере)определяет метод say и класс перестаёт быть абстрактным.
Фактически, данный код
Animal animal = new Animal() { @Override public void say() { System.out.println("i am animal"); } };
эквивалентен следующему:
class AnonAnimal implements Animal { @Override public void say() { System.out.println("i am animal"); } }; Animal animal = new AnonAnimal();

Как отсортировать целые числа от 1 до n так, чтобы каждое число, начиная со второго, делило сумму чисел, стоящих левее него, нацело

Массив всегда начинается с 1 и заканчивается каким-нибудь n и числа идут по порядку
Наример, есть массив [1,2,3,4,5] на выходе должно получится [3,1,4,2,5]
P.S. Имеется ограничение по времени - 1 секунда, а максимальная длина массива может быть до 10000 чисел (все числа идут по порядку и не повторяются)
Вот что пока выходит:
def check(a): #проверка подходит массив под условие или нет E = a[0] out = False for i in a[1:]: if(E%i==0): out = True if(E%i!=0): return False E=E+i return out
def sort(arr): #сортировка, тут у нас простой перебор комбинаций n = len(arr) for a in range(n): for b in range(n): if(b==a): continue E = arr[b] #сумма чисел стоящих левее for c in range(n): if(c==b): continue if(E%arr[c]!=0): #если сумма чисел стоящих левее делится на текущее нацело то меняем текущее и предыдущее числа местами temp = arr[c-1] arr[c-1] = arr[c] arr[c] = temp if(check(arr)): return arr #если массив проходим проверку возвращаем его
E=E+arr[c]


Ответ

Окончательный ответ. На С++, правда :)
#include #include
using namespace std;
int main() { int N; cin >> N; int m = N/2; for(int i = 1; i <= m; ++i) cout << (m+i) << " " << i << " ";
if (N % 2) cout << (2*m+1);
cout << endl; }
Итак, если это N = 2m, то мы пишем числа
m+1, 1, m+2, 2, ..., 2m, m
Если N = 2m+1, то
m+1, 1, m+2, 2, ..., 2m, m, 2m+1
Всё.
Промежуточный ответ не вытираю, все ж таки пример перебора с возвратом - иногда годится. Да и о том, как прочищает мозги информация о том, что решение существует - тоже :)
Прошу обратить внимание - сами видите, что условие "до 10000, 1 секунда" автоматом наводит на совсем другие рассуждения :) Никогда не ленитесь выкладывать полное условие!

Базовые стили браузеров

Какое решение в настоящий момент времени популярно, для нормализации (приведение всех стилей браузеров, к общему единому состоянию) базовых стилей браузеров, в процессе разработки проекта?
Пока я нашел три решения:
Сделать все самому, что бы точно знать как все будет устроено. Использовать - normalize.css Использовать - reset.css
Еще, я обратил внимание на некоторые сайты крупных проектов, и заметил, что они, не используют 2 и 3 вариант.


Ответ

Согласен с Oceinic , все уже есть в популярных фреймах, да и вообще браузеры уже давно стали придерживаться единых стандартов, хотя бы стремятся. А по существу отвечу, что 2 и 3 пункты очень стоит применять:
если будут векторы, шрифты и svg всякие. если верстка под мобильные браузеры.
Тут важно понять чего вы хотите добиться. Вообще сбросы CSS отменяют стили агента пользователя и возвращают множество элементов к их «обесстиленному» состоянию, некому ровному основанию, на котором можно безопасно строить. Однако затем нужно назначить стили большей части элементов до того, как вы сможете строить с их помощью. Задайтесь вопросами: - Оно вам надо? - Вы делаете свой bootstrap? Нет? Тогда используйте готовые фреймы, это очень сэкономит вам нервы и время.

Что такое поток (stream)?

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


Ответ

Поток это просто абстракция. Удобная абстракция для решения задач.
Но если так будет легче - считайте, что это такая труба. С одной стороны в нее пихаются данные, а с другой куда то уходят (например, на консоль или в файл). Так как труба не нулевого размера, часть данных там может "задерживаться" - это так называемая буферизация. Понимание этого может облегчить понимание некоторого странного поведения стандартных потоков.
Рассмотрим например, такое чтение с консоли:
int n; std::string s; std::cin >> n >> s;
и такие данные на вход:
123a aaa
Как это будет работать? Вначале стандартному потоку нужно прочитать число. Он будет читать до тех пор, пока там число. В n попадет 123. В "трубе осталось "a aaa". Дальше нужно прочитать строку. А строка читается до пробела или перевода строки. Поэтому прочитается только одно a. А многие полагают, что прочитается три а. Я привел этот пример не просто так. На него многие попадаются.
Как это реализовано внутри? Очень просто. Есть очередь (то есть, если очень грубо - массив), откуда читают данные байт за байтом. Если в очереди ничего нет - библиотечный код обращается к функциям операционной системы и читает с консоли/файла/сокета) и складывает в очередь. Конечно, в некоторых случаях эта очередь может быть реализована на базе операционной системы, а может и явно. Но для пользователя (то есть программиста) это прозрачно.
Аналогично работает и вывод.
Чем удобны потоки?
После того, как поток "подключен" к файлу или консоли, дальше все идет одинаково. Можно, к примеру написать функции, которые будут выводить в поток, но при этом абсолютно не знать, куда именно они выводят. Это позволяет писать обобщенные алгоритмы и прочие вкусности.
Например, нужно сделать функцию форматированного вывода числа на консоль (со спец. пожеланиями). Можно конечно закодить вывод на std::cout, но как протестить? Можно написать функцию, которая будет на вход получать ostream (предок std::cout) и выводить в него. Потом можно использовать такую функцию и выводить в stringstream, который легко преобразовывается в строку и результат можно выверить тестом.

C# и нейронные сети. С чего начать и в какую сторону смотреть?

Вопрос довольно общий, знаю.
Но я здесь немного уточню что бы было не так расплывчасто.
Интересует общая сжатая теория. С какой статьи лучше начать? Интересуют актуальные библиотеки C# Интересует приблизительная реализация уже созданной в нескольких вариациях идеи -- скармливаешь нейронке много изображений-пар: большое и маленькое. А нейронка учится делать из маленького большое и потом сравнивает сделанное большое и то большое которое ему скормили что бы понять что сделано не так. Какую нейронку лучше выбрать под даную задачу? Не слишком ли сложная и на сколько вообще реальная задачка в 3, если учесть что я вообще ни бум-бум в нейронных сетях? Если задача непосильная для новичка в НС, то с каких задач-тренировок лучше начинать?


Ответ

Одна из самых изысканных задач для НС приведена в этой статье, можно понять уровень проблематики и алгоритмов, которые задействуются для решений подобного класса задач и где действительно нужна НС. Примеры на OpenCV, что тоже замечательно.
OpenCV - Библиотека с самой открытой лицензией и исходным кодом, написана на C++. Под C# есть wrapper'ы - EmguCV, OpenCV for Unity (можно и без Unity использовать). Есть адаптация для Visual Studio (C++), Objective C, Android Studio, Python.
Даже для умеренно сложных задач НС обычно не нужна, и не очень даже применима - часто приходится делать обработку видеопотока в реальном времени, а НС не самая быстрая штука далеко. По этой и еще ряду причин большинство разработчиков, уверенных поначалу что им нужна НС, от этой идеи впоследствии отказываются. Благо в OpenCV реализовано огромное количество алгоритмов на все случаи жизни - почти всё, что связано с обработкой видео и изображений там есть.
После редактирования автором вопроса редактирую ответ :-)
Большинство алгоритмов, реализованных в доступных пакетах, в основном предназначены для down-scaling, спрос на это очевиден - камера снимает в большом разрешении, а в Интернеты лучше постить, предварительно уменьшив фотку - этим пользуются все активные пользователи Интернетов и соцсетей.
Up-scaling задача тоже достаточно хорошо проработана, просто спрос на нее несоизмеримо меньше - тем не менее любой дизайнер отлично знает, что нужно делать, чтобы изображение можно было без проблем увеличивать - взять Corel Draw или другой пакет векторной графики, то есть сделать изображение векторным.
Таким образом, если маленькое растровое изображение преобразовать в векторы, сделать up-scaling, мы скорее всего уже получим что-то интересное - обратите внимание на программу Potrace. В OpenCV готового для raster->vector ничего нет. Хотя из доступных инструментов и можно слепить что-то, врядли получится лучше чем у Potrace - всё-таки там люди занимались этой проблемой специально. Potrace идёт с исходниками и подробным описанием алгоритмов, так что простор для творчества полный :-)
И самое интересное на десерт - пора взглянуть на ваше увеличенное изображение, и путем сравнения с полученным в результате векторизации и up-scaling результатом выявить отклонения. Выявленные отклонения могут являться материалом для обучения НС. Например, можно пойти путем векторизации большого изображения, выявления соответствия кривых и сравнения их характеристик. По результатам обучения НС начнет выдавать некие рекомендации по коррекции кривых в произвольных изображениях. Может быть даже замахнуться на добавление кривых, типа дополнительных цветовых контуров градиента (хотя градиент в полученном изображении проще будет сгладить с помощью функций Blur и т.п.)

Java android программирование. С чего начать, не зная ничего? [дубликат]

На данный вопрос уже ответили: Книги и учебные ресурсы по Android 1 ответ Доброго времени суток, дорогие пользователи. Я только недавно начал увлекаться программированием (начал с JS) и понял, что это то, что мне нравится. Сейчас меня очень заинтересовало программирование под Андроид (сам имею ХТЦ Вайлдфайр, слабая модель и нормальных программ на него не очень много). И поэтому у меня появился вопрос. С чего можно конкретно начать программирование под андроид? Насколько я понял, самый легкий и практичный вариант - именно Джава. Но знания у меня полностью отсутствуют. Подскажите, с чего можно начать и где об этом прочитать? Заранее благодарю :) P.S. желательно с практическими примерами


Ответ

Ты правильно понимаешь, что начинать надо с JAVA. При устройстве потом на работу тебя будут тестировать одним из двух вариантов:
если есть техлид (а это будет джавист с опытом от 3-5 до ... лет), т.е. будешь работать под его управлением, то будут тебя тестить по знаниям Джава и не так уж по знанию SDK Android. Так что желательно после прочтения книги (или прохождения курса) по Java пройти сертификацию по Java (для себя - не обязательно сертификат получать). Тут важно понимать ООП и как ты его используешь при написании приложений, чтобы не было "говнокода". В вопросах с Андроидом очень важно понимать как работать с потоками и что такое процесс и стэк если техлида нет, а есть менеджер проекта, то скорее всего важны будут уже имеющиеся программы написанные тобою и вполне нормальный вариант, если дадут решить какое-то тестовое задание - к примеру в домашних условиях какую-то фичу на Андроиде сделать.
Желательно также учесть несколько моментов:
учить версию Java SE 6 (материала море, думаю найдутся те, кто лучше меня посоветуют где копать); по Android (книги на англ. конечно свежее контент имеют ...) на русском знаю из нормальных две книги (потоки в них не расписаны, так что гугл/хабр/книги-на-англ.):
для начинающих Программирование для мобильных устройств посерьёзнее Разработка приложений для Android конечно юзаем раздел на Хабре Разработка под Android. Там достают море подводных камней !!! спрашиваем на http://stackoverflow.com. Так сложилось, что там самые большие запасы инфы по разработке на Андроид. спрашиваем на http://androidforums.ru. На нашем языке, но интерфейс форума ... :) исходники, если надо, берём в открых источниках: http://code.google.com, bitbucket.org и конечно github.com

Выделение памяти типа auto

Почему данная строка не вызывает у разработчиков стандарта казуса?
auto p = new auto(42);


Ответ

Есть четыре вида длительности хранения памяти под объект (storage duration), и соответственно четыре способа создать объект:
статическая, static T variable(expression) потока, thread_local T variable(expression) автоматическая, T variable(expression) динамическая, new T(expression)
Было бы странно, если бы вывод типов работал бы только для первых трех способов, но не работал бы для динамически выделяемой памяти.

Почему Thread.Sleep ведёт себя неправильно? Как мне сделать задержку или длинные вычисления в графической программе?

Мне нужно выводить информацию пользователю с задержкой. К примеру, менять содержимое текстовой метки каждую секунду. (Или выводить промежуточные результаты длинных вычислений.) В программах командной строки я делал так:
Console.WriteLine("значение 1"); Thread.Sleep(1000); Console.WriteLine("значение 2"); Thread.Sleep(1000); Console.WriteLine("значение 3");
Это работало. Теперь мне нужно сделать то же самое в графической программе. Я написал метод
void OnClick(object sender, EventArgs args) { label.Text = "значение 1"; Thread.Sleep(1000); label.Text = "значение 2"; Thread.Sleep(1000); label.Text = "значение 3"; }
но он работает как-то не так. Промежуточные значения не показываются, а программа надолго перестаёт реагировать. А когда она отвисает, сразу показывает последнее значение.
Что происходит? Почему программа ведёт себя неправильно, и как же сделать правильно?


Ответ

Графические программы отличаются от консольных тем, что в них главный поток занимается многими вещами. В консольной программе у вас есть полный контроль, вы полностью управляете её пробегом. В графических программах вы запускаете приложение, и фреймворк для вас создаёт цикл сообщений. В этом цикле фреймворк обрабатывает передвижение мыши, нажатия на клавиши, изменения размеров окна, колбеки от таймера и тому подобные штуки, а также вызывает ваши обработчики событий, по одному на итерацию цикла (окей, это упрощённая картина, но для целей изложения подойдёт). После отработки итерации цикла выполнение переходит к следующей итерации.
Всё это работает в одном и том же потоке, который называется UI-потоком.
Теперь, что происходит, если вы в UI-потоке выполняете Thread.Sleep(1000)? А вот что: поток блокируется и ничего не делает целую секунду. Эту самую секунду ваш цикл сообщений простаивает, потому что поток выполнения заблокирован вами! Эту секунду не обрабатываются оконные сообщения, не происходит реакция на мышь, не вызываются колбеки, и даже не перерисовывается содержимое окна — ведь всё это делается в том же самом цикле сообщений, который мы заблокировали!
Чтобы программа работала нормально, ваши обработчики событий (наподобие OnClick), конструкторы объектов, и вообще весь код, бегущий в UI-потоке, должны пробегать максимально быстро, без задержек.
Как же сделать паузу в одну секунду? К счастью, в современной версии языка (начиная с C# 5) есть простое решение. Это async/await. Сделаем наш обработчик асинхронным (ключевое слово async), и заменим Thread.Sleep на await Task.Delay
async void OnClick(object sender, EventArgs args) { label.Text = "значение 1"; await Task.Delay(1000); label.Text = "значение 2"; await Task.Delay(1000); label.Text = "значение 3"; }
Этот метод работает правильно!¹
Что же произошло? Дело в том, что await Task.Delay на время ожидания не блокирует поток. На время ожидания метод как бы прекращает своё выполнение, и цикл сообщений больше не блокируется. [Будьте внимательны, он может быть заблокирован ещё где-то.] Когда ожидание оканчивается, цикл сообщений возобновляет выполнение метода с прерванной точки, до следующего await или до конца метода.²
Таким образом, наш код больше не блокирует UI-поток, и фреймворк может и дальше отрисовывать окно и заниматься прочими служебными заданиями.

А что делать, если вместо задержки нужно выполнить какие-то вычисления? Их так просто не вырезать из хода выполнения функции, они всё равно должны быть выполнены. Для этих целей их можно выгрузить в другой поток. Не пугайтесь, это очень просто. Вместо кода
label.Text = "парсим большой файл"; size = ParseBigFile(); label.Text = "закончили, результат = " + size;
вы пишете вот что:
label.Text = "парсим большой файл"; size = await Task.Run(() => ParseBigFile()); label.Text = "закончили, результат = " + size;
Task.Run выполняет ваш код в фоновом потоке, а на время этого выполнения функция опять-таки не блокирует UI-поток.³ Профит! Обратите только внимание на то, что из фонового потока нельзя считывать значения из контролов, поэтому их нужно считать заранее:
Было:
label.Text = "парсим большой файл"; size = ParseBigFileFromPath(textbox.Text); label.Text = "закончили, результат = " + size;
Стало:
label.Text = "парсим большой файл"; string path = textbox.Text; // читаем из контрола в UI-потоке size = await Task.Run(() => ParseBigFileFromPath(path)); // обращается к переменной label.Text = "закончили, результат = " + size;

В более старых версиях языка, без async/await, приходилось достигать того же самого более сложным образом. Например, заводить таймер, подписываться на его тики, и на них менять значения в контролах. При этом локальные переменные приходилось выносить в поля класса (или в специальную структуру-контекст). Или можно было делать грязные трюки с DoEvents. К счастью, те старые недобрые времена давно прошли.

Связанные вопросы:
Использование метода sleep() Работа с многопоточностью в c# Работа с Thread.Sleep(); Thread blocks window wpf

¹ Но для остальных асинхронных методов, не обработчиков событий, вы должны возвращать не void, а Task или какой-нибудь Task, чтобы вызывающий код мог дождаться их окончания и получить результат.
² Изложение грешит упрощениями, так что не принимайте его за истину в последней инстанции. Это примерная картина, а если вы хотите знать точную, лучше всего почитать книги или документацию. Или задать вопрос, если что-то ведёт себя непонятно.
³ Если вам нужно делать большую и длительную работу в фоновом потоке, то, возможно, имеет смысл выгрузить эту работу целиком и сообщать о результатах в UI через Progress

Как объяснить, что такое байткод?

Пытался объяснить начинающим инженерам, что такое байткод (в рамках пояснения принципов выполнения Java программ). Так вот, я пытаюсь стандартно объяснить, мол это что то между компиляцией и интерпретацией, типа каждая команда джавовского байт кода, это как несколько ассемблеровских комманд, но они смотрят на меня и говорят - не понятноооо! Они не программисты, не знают что такое ни компиляция, ни интерпретация, ни ассемблер, это я попытался на пальцах им объяснить, и вроде до них что-то дошло, а как можно на пальцах используя жизненные примеры объяснит принцип работы байткода?


Ответ

А нужно объяснять очень просто. Используя их положение. Для начала показываем этим инженерам программу на Java. Например, классический HelloWorld. И спрашиваем - понятно ли? Скорее всего они скажут нет. Объясняем, что и специальной программе, которая исполняет жава код, тоже не понятно. Для этого нужно "разобрать по косточкам". Теперь делаем "псевдотрасляцию" - как для машинистки (секретарши). Для HelloWorld'а она будет такая. настроить окружение (в коде этого нет, но это автоматом) - приготовить бумагу, проверить катриджи. взять из памяти строку "привет мир". нижимая кнопки, побуквенно ввести сроку (здесь появился цикл:) ). почистить все за собой и отнести бумагу заказчику. Формально - это и есть простой байткод. Только это человеческий байткод. А если в нем стандартизировать все операции и занумеровать, то все может быть сведено к набору чисел. Теперь к реальному байткоду перейти просто. Легко будет объяснить и переносимость. Если человек (секретарша) выучит все коды операций, то она сможет выполнить любую работу, главное, что бы была последовательность кодов. А инженеры могут попробовать спаять-сконструировать устройство, которое будет это исполнять.

Грамотная защита от SQL-Injection

Уже давно меня мучает вопрос: Как защитить свой сайт от SQL-Injection. В былые времена я использовал mysql_real string_escape для экранирования кавычек. Но прошло некое время, и я узнал про PDO, говорится, мол, эта тема неплохо поможет в защите сайта. Скажем, я не великий хакер и никак это не могу проверить, я знаю, что при mysql_real string_escape все кавычки и прочая ерунда экранировались - и вуаля, вы уже в домике.
Сейчас я работаю над своим проектом и решил проверить сайт на защиту проникновения. В результате, что я делал:
Я просто брал и вводил данные с кавычками, например, Infor`mat'ion. Как я уже говорил, я не великий хакер, но точно знаю, что вся эта дрянь должна экранироваться, но она так и заносилась в базу данных, что натолкнуло меня на мысль, что никакой защиты у меня, по сути, и нету. А данные я заносил вот таким вот образом:
$sql = "INSERT INTO chat (time, login, private, text) values(?, ?, ?, ?)"; $db->prepare($sql)->execute(array($time, $login, $private, $text));`
Этот метод я вычитал на хабре в "Почему стоит пользоваться PDO для работы с базой данных", подключение такое же, как и указано в статье.
Как можно защититься от этих инъекций?


Ответ

При использовании подготовленных выражений (prepared statement) параметры внешнего происхождения отправляются на сервер отдельно от самого запроса либо автоматически экранируются клиентской библиотекой. Создаём таблицу drop_table. Далее $name = "Evil'); DROP TABLE drop_table;--";
$sql = "INSERT INTO `test` (`name`) values('{$name}');"; $statement = $db->prepare($sql); $statement->execute(); Таблица drop_table успешно удалена. :) Теперь тот же запрос, но только через prepared statement: $sql = "INSERT INTO `test` (`name`) values(?);"; $statement = $db->prepare($sql); $statement->execute([$name]); В таблицу test добавилась запись Evil'); DROP TABLE drop_table;-- UPDATE Таким образом, мы обезопасили себя от SQL injection, но не защитили от XSS В последнем случае требуется: валидация. К примеру, если необходимо оповестить пользователя о недопустимости введёных им данных либо для логирования; санитизация. Приведение данных к соответствующему типу (int)$age. В PHP существует набор фильтров, созданных именно для таких случаев; использования облегченного языка разметки. Markdown - именно им Вы и пользуетесь на хэшкоде, либо можно задействовать старичка bbCode. В идеале заставить не только рядового пользователя, но и администрацию сайта пользоваться им. В целях оптимизации, (чтобы каждый раз не парсить), можно воспользоваться key-value storage (memcached, redis,...) для хранения html версии. Если по каким-то причинам требуется хранить в базе html от источника, который не вызывает доверие, то можно воспользоваться HTML Purifier Немного рекламы: :) для валидации: Rock Validate для санитизации: Rock Sanitize

Что означает оператор => в PL/SQL?

Вступление
До смешного мелкий вопрос, и все же гугл плохо реагирует на спец знаки, выдавая вариации на тему "больше или равно" >=, но тут у нас какой-то переход и я не понимаю смысл (пытаюсь разобрать чужой код).
Суть
Есть вызов функции:
if not mypkg.myfunc ( param_1 => PARAM_1, param_2 => PARAM_2) then ... end if;
Вот и возникает вопрос, что это за морфема в месте ввода параметров, где имена параметров отличаются только регистром?


Ответ

В Oracle PL\SQL при вызовах процедур и функций можно явно указать какому параметру какое значение передается.
<процедура>(<имя_парметра_2> => <значение_параметра_2>, <имя_парметра_1> => <значение_параметра_1>);
Что это дает?
Если у нас есть несколько перегруженных функций, с разными типами параметров, то иногда это единственный способ вызвать нужную нам функцию. Можно указывать параметры в произвольном порядке Улучшает читаемость кода

В чем суть ковариантности и контравариантности делегатов?

Изучаю по книге работу с делегатами и есть там пример, объясняющий, что такое ковариантность и контравариантность. Решил подробнее поискать в гугле, но объяснений так и не нашел. В книге сказано, что ковариантность позволяет присвоить делегату метод, возвращаемым типом которого служит класс, производный от класса, указываемого в возвращаемом типе делегата. А контравариантность позволяет присвоить делегату метод, типом параметра которого служит класс, являющийся базовым для класса, указываемого в объявлении делегата. К сожалению в практике это так разобрать и не смог, может кто сможет разжевать данный пример подробнее или преподнести свой, более легкий?
class X { public int Val; }
class Y : X { }
//Этот делегат возвращает объект класса X и принимает объект класса Y в качестве аргумента delegate X ChangeIt(Y obj);
class CoContraVariance { //Этот метод возвращает объект класса X и имеет объект класса X в качестве параметра static X IncrA(X obj) { X temp = new X(); temp.Val = obj.Val + 1; return temp; }
//Этот метод возвращает объект класса Y и имеет объект класса Y в качестве параметра static Y IncrB(Y obj) { Y temp = new Y(); temp.Val = obj.Val + 1; return temp; }
static void Main() { Y Yob = new Y();
ChangeIt change = IncrA; X Xob = change(Yob);
Console.WriteLine("Xob: {0}", Xob.Val);
change = IncrB; Yob = (Y)change(Yob);
Console.WriteLine("Yob: {0}", Yob.Val);
Console.ReadLine(); } }


Ответ

Для начала, давайте глянем, что такое эта самая вариантность.
Пусть у нас есть два класса, Car и BMW. Очевидно, что BMW есть подкласс Car: каждая бэха является машиной.
Обычно при этом говорят так: «везде, где вы используете Car, можно использовать и BMW». Это на самом деле почти правда, но не совсем.
Пример: если у вас есть список машин, вы не можете вместо него использовать список BMW. Почему? А вот почему. Пускай вас есть List, и вы используете его как список машин. Тогда, раз это список машин, в него можно добавить и Запорожец Lanos, правильно? Вот тут-то и начинаются проблемы. Если у вас в коде написано:
List bmws = new List(); List cars = bmws; // поскольку список БМВ - это список машин cars.Add(new Lanos()); BMW bmw = bmvs[0]; // ой.
Внимательно посмотрите на этот код и подумайте над ним: он иллюстрирует проблему. (И он не откомпилируется: язык C# спроектирован так, чтобы не приводить к проблемам.) Проблема с записью в список. Если мы в список добавим произвольную машину, будет очень плохо: мы сможем нарушить гарантии, которые даёт нам система типов!
Если бы у нас был список, доступный только на чтение, то проблем бы как раз не было:
IEnumerable bmws = new List() { new BMW() }; IEnumerable cars = bmws; // а так можно //cars.Add(new Lanos()); // <-- не скомпилируется
Итак, что у нас получается? Несмотря на то, что BMW — машина, список BMW уже не обязательно является списком машин. А вот список BMW, доступный лишь на чтение, таки является списком машин.
Есть?
Теперь назад к вариантности. Мы говорим о ковариантности в общем смысле, если что-то меняется аналогичным образом. В случае наследования классов: мы можем вместо Car использовать BMW, и точно так же мы можем вместо IEnumerable использовать IEnumerable

Окей, это было длинное вступление, теперь вернёмся к теме: ковариантность делегатов. Пусть у нас есть делегат, зависящий от типа Car. Поменяем в его определении Car на BMW, можно ли новый делегат использовать вместо старого?
Давайте рассуждать логически. Если у нас есть такой делегат:
public delegate Car Replace(Car original);
(он принимает на вход Car, и выдаёт другой экземпляр Car), то можно ли вместо него подставить функцию, описывающуюся делегатов такого вида:
public BMW MyReplace(BMW original) { ... }
? Разумеется, нет, потому что делегат может принимать на вход любую функцию, а наша функция хочет только BMW. Так что здесь ковариантности нету: такую функцию нельзя использовать там, где требуется данный делегат.
А вот если наш вариантный тип данных (то есть, Car) находится лишь в позиции возвращаемого типа:
public delegate Car Create();
то на его месте можно использовать функцию такого вида:
public BMW CreateBmw() { ... }
(если подходила любая машина, то BMW тоже подойдёт).
Это и есть ковариантность делегатов: там, где от вас в коде требуется делегат, вы можете вместо него предоставить ковариантный делегат.
Пример кода, использующий это:
// это функция, принимающая делегат: Car PrepareCar(Create carCreator) { Car car = carCreator(); car.ManufacturingDate = DateTime.Now; car.Mileage = 0; return car; }
// это функция, которая ковариантна Create: она возвращает не Car, а BMW BMW BmwFactory() { var bmw = new BMW(); bmw.EnginePower = 400; return bmw; }
// вы можете использовать эту функцию как аргумент PrepareCar // хотя её сигнатура другая: return PrepareCar(BmwFactory);

Контравариантность работает в другую сторону: там вы можете использовать делегат, работающий с базовым типом там, где ожидается делегат с производным типом. Такое работает для аргументов функций:
delegate double BmwTester(BMW bmw);
void TestAndPublish(BmwTester tester) { var bmw = new BMW(); double testResult = tester(bmw); PublishResult(testResult); }
double UniversalTester(Car car) { return 5.0; }
// вы можете использовать UniversalTester, хотя у него и не совсем подходящая сигнатура TestAndPublish(UniversalTester);
Это работает по тем же причинам, что и ковариантность: если тестеру подходит любой тип машины, то он сможет работать и с BMW тоже.

Почему интерфейсы упрощают жизнь?

Ранее никогда не писал собственные интерфейсы для "упрощения жизни". Почему? Что в них такого интересного?
В комментариях попросили добавить в вопрос мои знания и область работы. Пишу android приложения и... Все. Об интерфейсах не знаю ничего, только то, что можно класс от интерфейса наследовать и переопределить методы. Но зачем? Смысл интерфейсов?
Спасибо за замечательные ответы!


Ответ

Лично для меня самым наглядным для понимания сущности интерфейсов являются коллекции и все, что с ними связанно. Скорее всего это так, потому что с ними приходилось чаще всего работать.
Одна из главных особенностей ООП - избавление от дублирования логики, за счет правильной архитектурной составляющей. Для данного случая (в общем понимании) и были придуманы интерфейсы и абстрактные классы.
Допустим у меня есть сферический в вакууме метод, делающий какую-то работу с коллекцией:
/*Здесь может быть любой тип коллекции, который реализует соотв. интерфейс. Причем я использую интерфейс самого "низкого" уровня, т.к. он полностью покрывает данный функционал (т.е. проход по элементам в цикле) Также я могу написать любую свою реализацию для этого интерфейса */ public void showCollectionAtConsole(Iterable col){ col.forEach(object -> System.out.println(object)); }
Удобство здесь в том, что только в самой Java довольно много реализаций данного интерфейса, (подробнее) и я могу использовать данную логику для каждой из них.
Теперь у меня есть другой метод, реализующий какой-то функционал:
public boolean removeOrAddMyObject (Collection col, MyObject object){ //Если удалил объект - true, иначе - false boolean isRemove = true;
if (col!=null){ if (col.isEmpty() || !col.remove(object)) { col.add(object); isRemove = false; } }else throw new IllegalStateException("Коллекция = null");
return isRemove; }
Здесь мне приходится использовать три метода коллекции: isEmpty(), add(), remove(). Однако все эти методы описаны в интерфейсе Collection и нет нужды в качестве аргумента передавать более "высокий" интерфейс или класс с реализацией. Как я уже писал выше, данное решение позволит мне с чистой совестью переиспользовать неоднократно данный метод для других реализаций.
Также, как мне кажется, отличным примером использования интерфейсов являются Callback'и:
public final class MyClass {
static class MyObject { int id; String name;
public MyObject(int id, String name) { this.id = id; this.name = name; }
public void setId(int id) { this.id = id; } public void setName(String name){ this.name = name; }
@Override public String toString(){ return "My Object: id = "+id+", name = "+name; } }
//Интерфейс коллбэка interface MyCallback { void doSome(T myObject); }
static void doSomeAwesome(MyObject object, MyCallback callback) { System.out.println(object); callback.doSome(object); System.out.println(object); }
public static void main(String[] args) {
MyObject myObject = new MyObject(1,"someName");
MyCallback callback = new MyCallback() { @Override public void doSome(MyObject myObject) { myObject.setId(2); myObject.setName("someOtherName"); } };
doSomeAwesome(myObject,callback); } }
Суть сводится к тому, что в интерфейсе коллбэка вы явным образом определяете дженерик (если хотите передавать в метод параметры и/или получать из метода объекты) и описываете контракт. В моем случае это один метод, принимающий на вход аргумент. Теперь, я могу реализовать метод коллбэка на свое усмотрение, и таким образом расширить использование метода doSomeAwesome() дополнительной логикой.
Если выполнить код на выходе будет:
My Object: id = 1, name = someName My Object: id = 2, name = someOtherName
UPD: Также следует понимать, что есть и другие контексты для использования интерфейсов:
контекст множественного наследования (в Java нельзя наследоваться от более 1 класса, но можно имплементировать более 1 интерфейса) интерфейс как прослойка между взаимодействующими сущностями. Т.е. есть два модуля в программе которые выполняют разные функции и при этом взаимодействуют друг с другом. В идеальной ситуации оба модуля должны представлять друг для друга "черный ящик" с необходимым минимумом методов, описываемых интерфейсами. Таким образом куда проще избежать сложностей при последующей отладке кода. контекст проектирования архитектуры приложения. Как правило, на начальном этапе проектирования архитектуры будущего приложения, очень удобно "прикидывать" взаимодействие между сущностями с помощью интерфейсов. Это как будто черновой вариант, который не требует "заморачиваться" с реализацией, и позволяет относительно безболезненно модифицировать архитектуру на ранних этапах. контекст тестирования. Как уже упоминали в одном из ответов, использование интерфейсов позволяет: "использовать Mock-объекты вместо настоящих". Поверьте, в перспективе это очень облегчает жизнь.

Отличие ArrayList от LinkedList?

В чем отличие LinkedList от ArrayList? И в каких случаях на практике удобней использовать LinkedList?


Ответ

ArrayList - это список на основе массива. LinkedList - связанный список на основе элементов и связи между ними. В качестве LinkedList лучше всего подходит представление вагонов поезда сцепленных последовательно.
ArrayList следует использовать, когда в приоритете доступ по индексу, так как эти операции выполняются за константное время. Добавление в конец списка в среднем тоже выполняется за константное время. Кроме того в ArrayList нет дополнительных расходов на хранение связки между элементами. Минусы в скорости вставки/удаления элементов находящихся не в конце списка, так как при этой операции все элементы правее добавляемого/удаляемого сдвигаются.
LinkedList удобен когда важнее быстродействие операций вставки/удаления, которые в LinkedList выполняются за константное время. Операции доступа по индексу производятся перебором с начала или конца (смотря что ближе) до нужного элемента. Дополнительные затраты на хранение связки между элементами.
Одним словом - если часто вставляете/удаляете - выбирайте в пользу LinkedList, в противном случае ArrayList

Что в Javascript значит синтакс ( function(){…} )( param1, param2); ?

Столкнулся в этом примере с синтаксисом, который раньше не встречал: for (var state in aus) { ... (function (st, state) { ... })(aus[state], state); } Что означает эта конструкция внутри цикла?


Ответ

Чтобы избежать недостоверных данных, которых в данном треде достаточно, вставлю и свои пять копеек:
на подобный вопрос я уже отвечал - Проблема с обработчиками в цикле, только там подобный синтаксис был решением проблемы
собственно, что это IIFE - Immediately-Invoked Function Expression, и для чего её можно применять уже описано здесь же, но почему этот подоход используется именно в скрипте из ссылки:
for (var state in aus) { ... (function(st, state) { st[0].onmouseover = function() { /* мы знаем, что функция onmouseover - асинхронная, т.е. мы не можем достоверно сказать когда она выполнится, но точно после выполнения цикла, следоватльно, после выполнения цикла aus[state] - будет указывать на последнее значение, которые было получено в цикле, что не соответсвует нашим ожиданиям, для этого aus[state] копируется в переменную st, которая на каждой итерации цикла указывает на необходимый aus[state], тоже самое с переменной state*/ ... }; st[0].onmouseout = function() { /*здесь ситуация аналогичная*/ ... } })(aus[state], state); }
поэтому всегда, когда в цикле оперируем с асинхронными функциями, будь то таймауты, обработчики событий или колбэки, всегда искользуется подобная техника
Тонкости ECMA-262-3. Часть 6. Замыкания.

Склонения слов на PHP

Есть такая небольшая статистика
"N" Человек просят сейчас помощь!
if (n == 1) => "1 человек просит сейчас помощь" elseif ($n == 2) => "2 человекА просЯт сейчас помощь"
и так далее.
Как это сделать?


Ответ

function declOfNum($num, $titles) { $cases = array(2, 0, 1, 1, 1, 2);
return $num . " " . $titles[($num % 100 > 4 && $num % 100 < 20) ? 2 : $cases[min($num % 10, 5)]]; }
echo declOfNum(5, array('человек просит', 'человека просят', 'человек просят'));

Порядок элементов при сравнении на равенство

Можно написать условие вот так:
if (repository == null) {}
а можно вот так:
if (null == repository) {}
В чем разница?


Ответ


Условиями Йоды (Yoda Conditions) называется приём этот. Первой константа ставится, если ошибётесь и используете = вместо == вы, указал на эту ошибку компилятор вам чтобы. В Java это несущественно, т.к. ошибка будет почти всегда, исключение описано в соседнем ответе.
Есть другой случай, когда порядок сравнения имеет значение в Java — .equals(). Предположим, у вас есть объект, который вы получаете извне метода и образец для сравнения.
if (foo.equals(sample)) {...}
Если сравнивать так, что может случиться, что полученный объект будет равен null и тогда будет выброшено исключение. А ещё это может быть хитрый объект, в котором .equals() переопределено так, чтобы всегда возвращать true
Гораздо надёжнее сравнивать в обратном порядке:
if (sample.equals(foo)) {...}

Зачем использовать функции для выполнения программы?

Чем лучше использование функций для выполнения программы?
К примеру:
#include
void F0() { printf("Hello World") ; }
int main() { F0(); getchar(); return 0; }
Ведь можно в main выполнить команды ?


Ответ

Функции служат структурированию вашей программы.
Если вам качество программы неважно (например, программа простая, или вы не собираетесь её дальше разрабатывать и поддерживать), во многих случаях без функций можно и обойтись (важный контрпример: рекурсия).
Но если вы хотите сделать код легко читаемым, понятным, поддерживаемым, расширяемым, то вам нужно его структурировать: разделить на осмысленные части, и дать им имя. Это и есть ваши функции.
Заметьте, что вы в любом случае пользуетесь библиотечными функциями, наподобие getchar(): разработчики библиотеки уже структурировали её для вас.

Функции — не единственный метод структурирования программы. Например, ещё одно популярное, более мощное средство структурирования — классы.

Для чего нужны классы?

Не понимаю, для чего нужны классы в PHP?
Допустим, есть function.php, в нём много много функций, выполняющих разные действия, функции частично содержат общие переменные и в некоторых случаях части их кодов совпадают.
Если все эти функции превратить в методы и засунуть в один класс, что изменится в лучшую сторону или по другому - для чего нужны классы?


Ответ

Пример работы с БД: $con = db_connect($data); $query = db_query($con, $data); $fetch = db_fetch($query); Опять же, нужна глобальная переменная $con, проверка результата каждый раз и т.п. Или вот класс: /** * @author * * @todo */ class Db { private $con, $query, $fetch; /** * */ function __construct($data) { return $this->con = db_connect($data); } /** * */ function query($data) { if($this->con) { $this->query = db_query($this->con, $data);
return $this; } else { throw new Exception('no connection to db'); } } /** * */ function fetch() { if($this->con) { return $this->fetch = db_fetch($this->query); } else { throw new Exception('no connection to db'); } } /** * */ function __destruct() { db_close($this->con); } /** * */ public static function create($data) { return new Db($data); } }
$Db = Db::create('host:localhost;login:1234...');
$fetch = $Db->query('SELECT * FROM db')->fetch(); Простенько запускаем, делаем запрос и выводим результат. Красиво, удобно.