Страницы

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

понедельник, 10 декабря 2018 г.

Выбор формата сообщений: XML, JSON, Protocol Buffers для протокола

Поставлена задача разработать протокол уведомления двух устройств. Оба устройства подключены друг к другу по сети (Ethernet). На одном устройстве Linux, на другом Real-time OS. Нужно создать протокол, по которому устройства будут уведомлять друг друга о событиях. Реализация запланирована на C поверх TCP/IP. На данный момент выбор такой: свой собственный формат, XML или JSON, Protocol buffers. Вопрос в том, что проще в использовании, легче в поддержке, развитии, проще в реализации?


Ответ

Моя субъективная оценка: Protocol Buffers Поддерживается Google для внутренних сервисов Куча готовых реализаций Переносимый кроссплатформенный формат Бинарный формат (следствие - небольшой размер сообщений) XML Жутко избыточный Парсится небыстро JSON Занимает меньше, чем XML Сам по себе проще - проще и быстрее парсится Мой выбор в порядке приоритета: Protocol Buffers JSON XML В любом случае, не писал бы реализацию ни одного из форматов с нуля.

Как получить аватарку определенного пользователя vk на php?

Вообщем есть у меня блог на php, но в апи вконтакте я теряюсь, поэтому спрашиваю тут. Как мне вывести свою личную аватарку и статус из вконтакте в свой блог? Чтобы при изменении их во вконтакте они менялись и на блоге. Думаю многим блоггерам интересно как это сделать.


Ответ

Создайте приложение iframe Скачайте APIServerPHPClass.zip Там есть файл vkapi.class.php, добавьте этот файл в ваш сайт. Далее получаем свои данные профиля ВК: require 'vk/vkapi.class.php'; #путь к файлу vkapi.class.php $api_id = '0000'; #id приложения $secret_key = 'secret'; #секретный ключь приложения $user_id = '1'; #Ваш ID ВКонтакте //включаю библиотеку VK $VK = new vkapi($api_id, $secret_key); $prof = $VK->api('getProfiles', array('uids' => $user_id, 'fields' =>'first_name,last_name,photo_100,status,screen_name')); $adsd = sizeOf($prof['response']); for ($d = 0; $d < $adsd; $d++) { echo '

';} CSS (Стиль мини-профиля): profile.css Пример: http://bit.ly/10OHg9e

Выбор CMS для интеграции в существующий ASP.NET MVC проект [закрыт]

Существует крупный проект на ASP MVC (в сфере электронной коммерции). Необходимо внедрить в неёё систему управления контентом (CMS) для возможности хранить, редактировать и публиковать новости а также добавления мультиязычности на сайт. Помогите, пожалуйста, выбрать существующую CMS для решения (CMS должна быть на ASP).


Ответ

Ни одна из существующих CMC не даст Вам такой возможности. Одно дело собирать страницы, другое интеграция приложенний для совместной работы. Это всё равно, что пытаться поставить двигатель одной машины на совсем другую. Либо вам придётся подогнать свой сайт под конкретную CMS, т.е. собрать его в этой CMS. Либо писать свою CMS, что ещё сложнее. Одним словом нужно много поработать.

Культура программирования

Хотелось бы узнать о культуре программирования в php. много интересует например нужно ли проверять например функции которые находяться в другом файле или проверять сами файлы есть ли они вообще и т.д. где можно об этом почитать?


Ответ

Обновляемый набор лучших практик:
http://www.phptherightway.com/
Перевод на русский (на момент написания этого поста отставал от оригинала на английском на год):
http://getjump.me/ru-php-the-right-way/

Чем заменить тег br?

Чем можно заменить тег
, чтобы не повторять его множество раз в html разметке?


Ответ

например:

или:

Число, кратное 2^n

Из float A, которое может принимать любое значение, нужно получить число, кратное 2n Например, если A = 345.53;, то результат должен быть равен 256.
Пока что в голову ничего, кроме использования условного оператора, не приходит, но это не совсем подходит, но думаю, есть вариант экономнее, так как выполняется это при рендеринге, что и не должно влиять на fps.


Ответ

Простое решение "в лоб" на C (для сравнения скорости):
#include #include int main() { volatile double A=345.53; volatile double r; for(int i=100000000; i--;) r= exp2(floor(log2(A))); printf("%f
", r); }
volatile поставил чтобы было честное вычисление, а не результат спрогнозированный оптимизатором. Проверил на 2х машинах:
Celeron(R) Dual-Core CPU T3100 @ 1.90GHz Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz
Время счёта 17.812 и 9.288 секунд соответственно.
Быстрый переносимый вариант (только тело цикла):
int exp; frexp(A, &exp); r= ldexp(.5, exp);
Время счёта 6.240 и 1.768 секунды.
Вариант зависимый от представления в расчёте на то, что FLT_RADIX==2
r= scalbln(1, ilogb(A));
Последний вариант у меня оказался на селероне немного медленнее -- 7.488 секунд, а на коре немного быстрее -- 1.204 секунды.

Разделяй и властвуй: подсчет количества инверсий в массиве

Есть функция для подсчета инверсий в массиве, требующая О(n2) времени:
static void Inverses(int[] A, ref int count) { count = 0; for(int i = 0; i < A.Length - 1; i++) { for (int j = i + 1; j < A.Length; j++) { if( A[i] > A[j] ) count++; } } }
Также есть функция сортировки массива подходом разделяй и властвуй, требующая O(n*log(n)) времени:
static Int32[] Merge_Sort(Int32[] massive) { if (massive.Length == 1) return massive; Int32 mid_point = massive.Length / 2; return Merge(Merge_Sort(massive.Take(mid_point).ToArray()), Merge_Sort(massive.Skip(mid_point).ToArray())); }
static Int32[] Merge(Int32[] mass1, Int32[] mass2) { Int32 a = 0, b = 0; Int32[] merged = new int[mass1.Length + mass2.Length]; for (Int32 i = 0; i < mass1.Length + mass2.Length; i++) { if (b < mass2.Length && a < mass1.Length) if (mass1[a] > mass2[b]) merged[i] = mass2[b++]; else //if int go for merged[i] = mass1[a++]; else if (b < mass2.Length) merged[i] = mass2[b++]; else merged[i] = mass1[a++]; } return merged; }
Нужно реализовать алгоритм подсчета инверсий в массиве с подходом разделяй и властвуй, которому требовалось бы O(n*log(n)) времени.
К сожалению, мне достаточно тяжело дается понимание рекурсии, когда первый метод вызывает другой метод, а другой вызывает первый при условии.


Ответ

Вам сначала нужно разобраться с сортировкой слиянием, а именно понять идею алгоритма, а потом уже разбираться с инверсией.
Скажу кратко: мы разбиваем массив на две части, каждую из этих частей, в свою очередь, тоже разбиваем на две части и т.д., пока наши части не будут состоять из одного элемента. После разбиения мы сливаем парами части в одну так, чтобы результирующая часть была отсортирована - сравниваем элементы одной части с элементами другой соответственно и записываем их в нужном порядке в результирующую. Затем полученные части мы опять попарно сольем и т.д., пока у нас не останется одна часть, которая и будет являться отсортированным массивом.
Текстом трудно понять, поэтому рекомендую посмотреть графическую демонстрацию (на той же википедии есть гифка). Когда поймете идею, уже можно вникать и в реализацию.
Насчет инверсий
Когда мы сливаем обе части, как я уже говорил, мы сравниваем элементы одной (первой, левой) части с элементами другой (правой, второй) части соответственно. И если элемент левой части больше элемента правой части соответственно, то значит это и есть инверсия. И так же все оставшиеся элементы левой части тоже будут больше, т.к. левая и правая часть отсортированы. Поэтому количество инверсий нужно увеличить на количество оставшихся элементов + 1 (текущий элемент).
UPD:
Вот и пример.
Индексация идет с 0. Не описывал, что добавляем элементы в результирующую часть, думаю, это и так понятно. Описал только те части, в которых есть инверсии. Возможны ошибки, т.к. быстро делал. Да и пришлось так сжато уместить элементы, чтобы картинка полностью отобразилась на хэшкоде.

Python. Подмена библиотеки из site-packages

Есть десктопная программа на Python, которая использует библиотеку (для определенности - pygments, хотя это не так важно). Чтобы пользователю не нужно было заботиться о зависимостях, библиотека pygments поставляется вместе с программой и вполне успешно используется.
Но дело в том, что в самом pygments есть много кода вида
from pygments.bla_bla_bla import ...
Возникают проблемы, если у пользователя в системе уже установлен pygments, тогда при импорте Python ищет модуль pygments сначала в site-packages и успешно находит. Но нужно сделать, чтобы независимо от того, установлен ли pygments в системе глобально, использовалась именно та версия, что прилагается к программе.
Можно ли это сделать, не трогая код библиотеки pygments?


Ответ

Здравствуйте. Вариант "в лоб"
import sys sys.path.insert(0,'catalog_with_your_pygments') import pygments
Также может помочь virtualenv, или смена архитектуры Вашего приложения.

Влияют ли указатели на производительность?

Появился вопрос связанный с этим кодом, а конкретнее с функцией square. Когда у функции скорость выполнения будет больше, с использованием указателей или без них? Я где-то слышал или читал, что с указателями будет бытрее, потому что при их использовании не создается дополнительная переменная, это так?
#include
float square(float *number);
int main() { float number = 4.0; float second_number = square(&number);
printf("Number two = %f
", second_number); printf("Number = %f
", number);
getchar(); return 0; }
float square(float *number) { return *number * *number; }


Ответ

Давайте для начала отставим cargo cult. Быстрее не потому, что «с указателями», быстрее потому, что эффективнее. Для того, чтобы понять, как будет эффективнее, вы должны понимать, что именно происходит и где именно теряется скорость. Без этого ваш вопрос похож на «будет ли еда вкуснее, если досыпать сахара?»
В вашем случае при компиляции в release mode функция будет вшита в точку вызова и различий вовсе не будет. Компиляторы, поверьте, умеют оптимизировать гораздо лучше вас.
Вы допускаете типичную ошибку новичка: пытаетесь оптимизировать (а) не разобравшись в том, как оно работает и почему, (б) в ущерб смыслу программы, (в) без предварительного профилирования. Не делайте так.

Для вашего случая разница могла бы быть с плохим компилятором, который не умеет оптимизировать. Для этого случая у вас есть передача 32 бит float против передачи 32 или 64 бит указателя, плюс затраты на косвенный доступ. Прикидывайте сами.
Но таких плохих компиляторов уже нет. Кроме того, разницу в несколько наносекунд вы вряд ли заметите, расходы на старт программы или ввод/вывод (и случайные флуктуации внутри них) на порядки больше. А уж коммуникация с пользователем замедляет всё ещё на несколько порядков.

Что такое “ручки” на сленге программистов?

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


Ответ

Подозреваю, это может быть как-то связано с внешним видом реализуемых компонентом интерфейсов в UML, которые выглядят как рукоятки в механике/гидравлике:

Соответственно, "дернуть ручку" - воспользоваться интерфейсом.

Как настроить русский язык в Ubuntu Server 15.04?

В консоле вместо русских букв отображаются иероглифы (не квадратики - это я так понял другая проблема). Гугл отсылает к настройкам локали.
Что я уже сделал:
1) Установил пакеты с русским языком
2) Проверил список локалей - ru_RU.utf8 там есть
3) Посмотрел настройки текущую локаль, там написано так: LANG=ru_RU.UTF-8
Не пойму куда копать дальше... Кто-то знает что по данной проблеме?


Ответ

Попробуйте установить пакет поддержки кириллицы для консоли
sudo apt-get install console-cyrillic
После установки добавьте в файл /etc/rc.local перед exit 0
cyr
Перезагрузите ОС. Должно помочь.

Continuous Integration для PHP. Проясните принцип работы

Я прочитал достаточно теории и вроде как понял суть CI. Необходимо оптимально настроить автоматический билд приложения чтобы побыстрее пресечь различного рода ошибки при частой интеграции. Какой еще build для PHP? Насколько я знаю никаких билдов нету. Зачем запускаются разные phploc и прочие программы которые просто возвращают размер проекта. Зачем запускать эти CI сервера? Чем они помогают (в контексте PHP)? Автоматически запускают команды просто?


Ответ

Постоянная интеграция призвана решать много проблем сразу:
Исключение человеческого фактора из повторяемых процессов, и, собственно, повторяемость и воспроизводимость этих процессов. Если разработчик может случайно вывалить на продакшен конкретную версию приложения со своими изменениями или забыть в исправленный код отдельной ветке, то постоянная интеграция не дает разработчику это сделать - она устанавливает набор правил и позволяет разработчику пропустить через эти правила свой код, чтобы дать добро на выкладку или отрицательный фидбэк в связи с ошибкой. Предыдущий пункт выливается в то, что постоянная интеграция не способна забыть какие-либо вещи. В то время как в голове у разработчика умещаются плюс-минус последние две недели, интеграция будет сообщать о проблеме все то время, пока проблема существует. Тестирование (с которого, как правило, она начинается). Пока код выкладывается на продакшен без тестирования, никто не может сказать, работает ли он. Превращение кодовой базы в артефакт. Кодовая база - это просто текстовые файлы, артефакт - это готовое к работе приложение. В случае с PHP разница между двумя состояниями может быть минимальна и незаметна, но если вы, например, делаете phar-приложение, то непосредственно подготовкой этого phar-архива будет заниматься CI-сервер. Разработчик может несколько раз за день собирать этот архив, но финальную версию собирает машина, и именно она дает гарантии работоспособности архива. Автоматизацию процесса релиза проекта до одной кнопки. Разница с предыдущем пунктом тоже может быть не очень хорошо заметна, но артефакт - это просто какая-то сборка приложения, в то время как релиз - это конкретная версия приложения с каким-то функционалом. Сборка артефакта и прогонка тестов гарантируют, что приложение работает, но такой артефакт не обязательно содержит в себе весь функционал, который можно выложить, это может быть промежуточная версия - так, если руководитель запланировал в следующей версии веб-сайта новую админку и интеграцию с какой-нибудь соцсетью, то промежуточный артефакт может содержать что-то одно, а в релиз уходит только такой артефакт, который содержит все запланированное. Кроме того (!sic), релиз может состоять и из нескольких артефактов. Сам по себе релиз может быть и автоматическим. Полную автоматизацию процесса от выкладки кода в репозитории до выкладки артефактов в продакшен; в отличие от предыдущего пункта, человек полностью исключается из всей цепочки, а каждая успешная сборка автоматом становится релизом. Дополнительные артефакты, такие, как автоматическая документация (пресловутый PHPDoc), подписи артефактов (чтобы конечный получатель мог убедиться в том, что информация о сборке артефактов соотстветствует действительности). Дополнительный анализ кода. Тесты - это хорошо, но они говорят исключительно то, работает ли тот код, который был протестирован; они ничего не говорят о том, сколько кода было протестировано и насколько хорош этот код. Поэтому интеграция может включать в себя еще и дополнительные отчеты, например:
Общее покрытие кода тестами (e.g. 65% кода покрыто) Отчет о покрытии конкретных файлов, строк, логических ветвей и выражений. Здесь начинается самая мякотка, которая может выглядеть вот так - вы просто физически видите, какие строки и в каких тестах были покрыты. Более того, такие отчеты отлично интегрируются с IDE, что позволяет вам отслеживать подобные штуки на своей машине (оставляя CI для мониторинга общего тренда - покрытие растет или падает) Человекочитаемые отчеты о тестах. Когда вы тестируете код, вы формализуете проблему до сравнения реального результат с желаемым, и ошибка 'Failed asserting that 42 is true' или 'Failed asserting that server returned 200' вам ничего не скажет. Однако есть специальные фреймворки, позволяющие вам сгенерировать еще более вкусную мякотку с человеческими описаниями тестами (что мы тестируем? почему появился этот тест? что происходило во время теста? какой use-case проверяется в ходе этого теста?), прикладывать к ним аттачменты, мерять скорость выполнения тестов (если какой-то из них подвисает, то хорошо знать какой, верно? этакий test-insght). Конкретно сейчас я описываю мой любимый allure, но кроме него наверняка есть еще непочатый край утилит. Не пожалейте времени, сходите по ссылке - представляете, насколько вы упростите жизнь в сложном проекте, если к каждому проваленному тесту будет прилагаться (sic!) скриншот страницы, на которой не удалось совершить ожидаемые действия, список шагов, которые должны были быдь пройдены в тесте, конкретный браузер, в котором появились проблемы, и, наконец, какая-нибудь несмешная шутка? Отчеты о статическом анализе кода. Это очередная мякотка, которая надает вам по рукам, если вы строите слишком сложные циклы или пишете нечитаемый код. В то время как анализ реализации логики - это AI-complete задача (после решения которой программисты не очень и нужны, потому что логику может писать сама система), анализ правильно расставленных отступов, повторяемого кода и количества комментариев - это вполне разрешимая задача. Чтобы еще раз впечатлить вас, оставлю очередную ссылку, а чуть позже вернусь к этой теме. Автоматические ченджлоги и отчеты о вкладе команды в проект. Это уже очень специфичная и сложная тема, которой я не касался. Нагрузочное и прочее тестирование, приближенное к реальной жизни и не тестирующее код напрямую (в нетфликсе, например, не пропускают релизы, которые по показателям производительности хуже предыдущих и намеренно убивают серверы, чтобы проверить жизнеспособность системы в критических ситуациях). Если нас интересует конечный продукт, то почему бы не автоматизировать еще и проверку того, что он будет соответствовать нашим ожиданиям скорости? Проверку возможности слияния двух источников кода до реального слияния И, наконец, постоянная интеграция легко интегрируется (pun intended) с различными способами оповещения разработчиков. Следить за процессом билда - утомительное и ненужное дело, поэтому постоянную интеграцию можно настроить на уведомление только в тех случаях, когда изменения что-то ломают; в этом случае молчание системы автоматически означает, что либо все работает, либо интеграция тупо сдохла (это решается мониторингом, который я не буду здесь затрагивать).
Весь набор задач - создать артефакт, прогнать тесты, прогнать анализ - называется пайплайном, а однократное прохождение кодом пайплайна - билдом. Билд - это сам факт прохождения кодом постоянной интеграции, результатом которого могут быть вышеописанные артефакты и отчеты.
Как это все помогает проекту? Представим, что у нас есть некоторый виртуально-бесконечный проект с гигантским числом разработчиков, которых невозможно контролировать физически. Если у вас нет вышеописанного пайплайна, у вас нет возможности заглянуть в код и оценить состояние текущей кодовой базы, технического долга и вклада разработчиков в проект. На маленьких проектах это может настолько же виртуально-бесконечно не стрелять в ногу, но в случае с большим проектом это уже не прокатит, потому что начинают появляться следующие ситуации:
В продакшен ушел битый релиз с багами. В ходе разработки новых фич разработчики затронули старый код и все сломали. Кто виноват? Кто внес баг? Кто пропустил этот баг? Разработчики говорят, что нужен срочный рефакторинг. Как оценить, насколько он нужен, как расставить приоритеты при рефакторинге, где находятся наиболее горячие места? Разработчики говорят, что проект недопокрыт тестами и грозятся рисками выкатки нерабочего релиза. Как определить, правда ли это? Разработчики говорят, что у нас в целом ухудшается кодовая база. Опять клянчат рефакторинг, или все действительно идет по наклонной? Другие ситуации, для которых иссякла моя фантазия
Суммируя все вышенаписанное, CI дает вам возможность автоматизировать все рутинные процессы, перенести основные задачи тестирования на машину, нормализовать диалог между менеджерами / разработчиками / отделом качества продукта и проанализировать кодовую базу буквально что изнутри. Пока у вас нет этой штуки, вы не знаете, в каком состоянии текущий продукт, поэтому берете на себя все риски выпуска нерабочего продукта, внезапно открывшейся необходимости рефакторинга, траты времени на бэктрейс багов, возникающих в системах со сложной логикой. Безусловно, это не панацея, и баги, на которые не были написаны тесты, все равно уйдут в продакшен, но без всей этой штуки вы вообще не можете заглянуть внутрь и отследить техническое (и, возможно, не только) качество продукта.
Касаясь вашего конкретного примера с PHPLoc - он действительно бесполезен, если просто использовать его для подсчета веселых цифр. Но косвенно он дает вам способ проанализировать ваше приложение:
Каков объем кодовой базы? Если мы берем нового разработчика, с каким объемом кода ему придется ознакомиться, чтобы начать работать? Сколько у нас глобальных констант? Не работают ли у нас макаки? Что у нас с цикломатической сложностью? Корректно ли у нас разносится логика в коде?
Если в проекте участвуете только вы, и вы совершенно точно не используете глобальные константы, то он вам не нужен. Но если вы работаете в стартапе, где каждый день на счету, и зачастую вам приходится жертвовать качеством в угоду скорости, то вместо расставления todo по всему проекту вы можете мониторить те грязные участки кода, которые пришлось оставить, с помощью тех же phploc, phpcs, phpmd. Вопрос о том, насколько это нужно вашему текущему проекту - открытый, но сама возможность предоставить этот самый взгляд на код изнутри у вас есть.
Для закрепления впечатления - еще одна ссылка на CI вышеупомянутого Allure. Его разрабатывает команда автоматизации тестирования в Яндексе, и там можно посмотреть, как проходит билд - там есть и прогонка тестов, и тренды, и автоматический анализ качества через sonarqube.

Зачем нужен интерфейс? [дубликат]

На данный вопрос уже ответили: Отличия абстрактного класса от интерфейса (abstract class and interface) 12 ответов Зачем в java интерфейс, если есть абстрактные классы? Кроме множественного наследования, в чем главные различия?


Ответ

Разница в концепции.
Абстрактные классы помогают создавать иерархию с общими чертами. Важным тут является именно связь родитель — наследник. Например абстрактный класс «птица», ее наследники — конкретные виды птиц.
При использовании нам не важно, какая именно птица будет — мы используем ссылку с типом абстрактного класса. И используем методы «кричать», «ходить», «летать». Все ок, но что если не все птицы умеют летать? Например страус, пингвин.
Здесь нам могут помочь интерфейсы, которым не важна связь родитель — наследник, они задают правила поведения. Мы можем выделить метод «летать» в интерфейс и реализовать его у тех птиц, которые могут летать; при этом каждая птица может летать характерным только для нее способом. Так же мы сможем в будущем реализовать этот интерфейс у самолета и определить его способ полета.
Например, у нас на острове группа зверей, птиц, машин и нам надо переправить их на другой остров. В этом случае это сделают те, кто реализует интерфейс с методом «летать».
И здесь мы получаем две ветви полиморфизма, одна задает связь родитель —наследник, вторая — поведение.

Зачем нужен const в сигнатуре функции?

Например, у меня есть следующий код.
#include using namespace std; class X { int x; public: X(int i = 2): x {i} {}
void print() const {cout << x;} // ^^^^^ int getx() const {return x;} // ^^^^^ X operator-(const X& rop) {return x + 2*rop.x;} // ^^^^^ int operator-(int rop) {return 2*x + rop;}
};
int operator-(int lop, const X& rop) { // ^^^^^ return lop – rop.getx(); }

int main() { X x {6},y; cout << x – 3 – y; return 0; }
Подскажите, пожалуйста, каково назначение ключевого слова const в сигнатуре функций?


Ответ

Чтобы этот код мог работать с константными объектами. Это const означает, что вызов метода print() не изменит состояния объекта.
void print() const {cout << x;} int getx() const {return x;}
Здесь вы никак не меняете объект класса - поэтому нет никакого смысла делать НЕ const (мое мнение - лучше делать все, что только можно, с const, применяя его по умолчанию, и не использовать его только там, где это необходимо), зато эти методы можно будет вызвать, например, при передаче объекта в качестве константного параметра - вот как тут:
X operator-(const X& rop) {return x + 2*rop.x;}
Вы же никак не меняете rop, так что можете теперь вызывать оператор для любого объекта, в том числе временного.
Кстати, операторы я бы тоже делал константными, типа
X operator-(const X& rop) const {return x + 2*rop.x;}
поскольку они никак не меняют состояние объекта.

Алгоритм Евклида для вычисления НОД

В школьной презентации алгоритм Евклида описан так:
Заменяем большее из двух чисел разностью большего и меньшего до тех пор, пока они не станут равны. Это и есть НОД.
А я привык к такому алгоритму:
Большее число делим на меньшее. Если делится без остатка, то меньшее число и есть НОД (следует выйти из цикла). Если есть остаток, то большее число заменяем на остаток от деления. Переходим к пункту 1.
Откуда взят алгоритм, представленный выше? Обоснован ли он математически?


Ответ

Алгоритм Евклида полностью аналогичен "привычному", за исключением того, что он по древности своей считает остаток, отнимая по одному меньшему числу от большего, пока результат не станет меньше ЭТОГО меньшего, а Вы умеете сразу делить с остатком.

Перегрузка оператора сложения

class Cat { private: int value = 1;
public: Cat(int _value) { value = _value; }
operator+(Cat a, Cat b) { return new Cat(a.value + b.value); } };
Казалось бы все пишу правильно, сложение двух котов даст нового кота, у которого value будет суммой их value'ов. Но получаю две ошибки.
main.cpp:17:5: error: C++ requires a type specifier for all declarations operator+(Cat a, Cat b) { ^ main.cpp:18:16: error: cannot initialize return object of type 'int' with an rvalue of type 'Cat *' return new Cat(a.value + b.value); ^~~~~~~~~~~~~~~~~~~~~~~~~~ 2 errors generated.


Ответ

А кто будет объявлять тип возвращаемого значения?
Cat* operator+(Cat a, Cat b) { return new Cat(a.value + b.value); }
Только это - во-первых, не решение, а во-вторых, плохое решение.
Не решение - потому что вообще оператор + бинарный. Он складывает два значения, а у вас в сложении участвуют три - еще и ваш объект (this).
Cat* operator+(Cat b) { return new Cat(this->value + b.value); }
Теперь это решение. Но плохое. Потому что возвращает не кота, а указатель на него. В результате на вызывающую функцию перекладывается ответственность за обязательное сохранение значения и освобождение в дальнейшем памяти.
Этого можно избежать, если возвращать готового кота:
Cat operator+(Cat b) { return Cat(this->value + b.value); }
И последнее. Если кот большой (не в смысле значения value, а занимает много памяти) - то имеет смысл передавать его в оператор не по значению, а по ссылке:
Cat operator+(const Cat& b) { return Cat(this->value + b.value); }

Есть число в списке и нужно вывести соседние от него числа (слева и справа)

Есть список из чисел, я нашел в нем число с максимальным значением и хочу вывести соседние от него числа. Одно слева и одно справа. Не знаю, как их обозначить.
def A(linst) : v_max = max(linst) z = [x for x in enumerate(linst)] for i in z : if v_max in i and # finish


Ответ

Если макс число 0 индекс, то слева от него будет считаться последнее число списка, тоже самое и для если макс число последнее в списке:
def foo(numbers: list) -> tuple: max_num = max(numbers)
index_max_num = numbers.index(max_num)
left_index = index_max_num - 1 # Индекс последнего элемента if left_index < 0: left_index = len(numbers) - 1
right_index = index_max_num + 1 # Индекс первого элемента if right_index >= len(numbers): right_index = 0
return numbers[left_index], max_num, numbers[right_index]
print(foo([3, 6, -2, -6, 8, 3])) # (-6, 8, 3)
print(foo([1, 2, 3, 4, 5])) # (4, 5, 1) print(foo([1, 3, 5, 9, 2])) # (5, 9, 2) print(foo([5, 3, 1, 4, 2])) # (2, 5, 3)

JavaScript: как создать переменную через функцию?

Здравствуйте!
Подскажите, пожалуйста, можно ли в JavaScript создать и назначить переменной имя, переданной через аргумент функции?
Например:
function create_el(name){ var div = document.createElement("div"); div.id = name; document.getElementById("main").appendChild(div); //name = document.getElementById(div); //name должен стать test }
create_el('test'); console.log(test); // созданный элемент
Т.е. нужно в функцию передать имя, а на выходе получить переменную с этим именем. Спасибо!


Ответ

Создайте глобальную переменную в свойстве window. Например: function(a){window.a=a}. Далее просто используйте её.

Сократить множество if-else

Есть метод, который принимает строку и в зависимости от строки возвращает кортеж Tuple с одним int и одним string значением. Проблема в том, что если расписать это как if-else то получится более 20 вариантов. switch не сработает для непостоянного значения, а тернарный оператор - для 2 значений разного типа. Вопрос - как упростить данный метод:
public static Tuple Divide(string SubClass) { int Level = 0; string Class = string.Empty; try {
if (SubClass.Contains("investment")) { Class = "bonds"; RiscLevel = 2; return new Tuple(RiscLevel, Class); } else if (SubClass.Contains("speculation")) { Class = "bonds"; RiscLevel = 4; return new Tuple(RiscLevel, Class); }
// и еще много if-else
return null; } catch (Exception ex) { BOX.ShowError(ex.Message, ex.Source); return null; } }
В результате получается огромный массив if-else можно ли его как то сократить, сделать более удобочитаемым?


Ответ

Материализуйте ваши варианты в виде структуры:
class Case { public string SubClass { get; } public string Class { get; } public int RiscLevel { get; } }
Соответственно, ваш набор if-else превратится в foreach:
Case[] cases = { ... };
// ...
foreach (Case case in cases) if (SubClass.Contains(case.SubClass)) return Tuple.Create(RiscLevel, Class); return null;

Каков синтаксис для функционального аналога SELECT TOP(N) в Oracle?

Предположим, есть таблица TABLE
ID | DEF 1 | Один 2 | Два 3 | Три 4 | Четыре
Тогда запрос в MS SQL Server
SELECT TOP(2) * FROM TABLE ORDER BY ID DESC
Даст нам выдачу:
ID | DEF 4 | Четыре 3 | Три
А аналогичный запрос в Oracle (аналог, который мне предложился в интернетах)
SELECT * FROM TABLE WHERE ROWNUM <= 2 ORDER BY ID DESC
Даст нам выдачу:
ID | DEF 2 | Два 1 | Один
Как получить действительно аналогичный по функциональности синтаксис для Oracle?


Ответ

В оракле до 11-й версии включительно - через подзапрос с row_number
select * from (select t.*, row_number() over (order by id desc) rn from t) where rn <= 2
В 12-й версии появился синтаксис для первых N строк с LIMIT и OFFSET, почти как в постгресе (запрос скопипастил из интернета, 12-го оракла под рукой нет):
select * from t order by id desc OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY;

Создание новой БД в Oracle

Попытался вызвать CREATE DATABASE в Oracle и он меня послал:
Error report - ORA-01501: CREATE DATABASE failed ORA-01100: database already mounted
Хотя в MS SQL это прокатывало. Полез гуглить и наткнулся на документацию
Я правильно понимаю, что в Oracle на каждую БД нужно создавать свой экземпляр Oracle?
Немного не привычно после использования MS SQL Server, где можно много БД создавать на 1 экземпляр.


Ответ

Для целей логического разделения в Oracle служат "схемы" (фактически пользователи-владельцы). Для физического разделения служат табличные пространства. При этом логическое и физическое разделения действуют независимо, вы можете хранить все схемы в одном наборе файлов, а можете и одну разбить на несколько (например вынести архивные таблицы на боле медленные носители или отделить индексы от данных). При этом потребности создавать второй экземпляр на одной и той же машине обычно не возникает.
Для каждого независимого проекта, если вы хотите отделить все его объекты, вместо create database выполняйте create user.

Нахождение индексов нескольких наименьших чисел в списке. python

Как наиболее оптимальным образом найти индексы двух наименьших чисел в списке?


Ответ

Быстрый способ получить значения:
from heapq import nsmallest
nsmallest(2, some_list)
И их индексы:
a, b = map(some_list.index, nsmallest(2, some_list))

Фон страницы в виде диагональных линий

Для страницы сайта есть фоновая картинка в виде диагональных линий. Задавал ей background-repeat, но тогда стыковка заметна. При таком фоне наверное невозможно сделать маленький узор, а потом повторять его? Может на CSS лучше будет сделать, если такое возможно?


Ответ

Отключить фоновое изображение и сделать repeating-linear-gradient
body { background: repeating-linear-gradient(-45deg,#222,red 10px, gold 10px) fixed; }

Что быстрее при использовании много if, if-else или switch

В проекте есть много ситуаций где нужно проверить выбранное действие.
Что оптимальнее использовать:
Много If
if (...){} if (...){} if (...){}
If-else
if (...){} else if (...){} else if (...){} else if (...){} ...
Switch
switch(...){ case ONE: break; case TWO: break; case THREE: break; ... ... case N: break; }


Ответ

Оператор switch, как правило (то есть когда нетривиальный, в тривиальных случаях JIT его разберет на if/else) - транслируется в байткод tableswitch или lookupswitch
Производительность tableswitch O(1), а lookupswith O(log N) (то есть сравним с if/else/if)
P.S. перечень байткод инструкций

Что работает быстрее: массив или ArrayList?

Что работает быстрее? Прогнал тест 100 раз. Результаты всегда разные: то один быстрее, то второй. Так есть ли реальный выигрыш в использовании массива вместо ArrayList? ArrayList создавал с нужным размером сразу, чтобы время на "расширение" не тратилось. Проверялось быстродействие команды add. Пытался понять, уменьшит ли замена ArrayList на обычный массив в "узких местах" время выполнения (часто слышал такое предположение). Если в моем случае всегда известен заранее размер массива/листа. Результаты получились случайные. Иногда ArrayList значительно быстрее, иногда массив, иногда они равны. import java.util.*;
public class Main { private static int COUNT = 1000000;
private static double getPeriod(Runnable r) { System.gc(); Date date = new Date(); r.run(); return (new Date().getTime() - date.getTime()); }
private static void testList(final List list) { double period = getPeriod(new Runnable() { public void run() { for (int i = 0; i < COUNT; i++) { list.add(new Object()); } } }); System.out.println("List " + period); }
private static void testArray(final Object[] array) { double period = getPeriod(new Runnable() { public void run() { for (int i = 0; i < COUNT; i++) { array[i] = new Object(); } } }); System.out.println("Array " + period); }
public static void main(String[] args) { for (int i = 0; i < 100; i++) { List arrayList = new ArrayList(COUNT); Object[] array = new Object[COUNT];
testList(arrayList); testArray(array); } } }


Ответ

Обычный массив почти наверняка будет выигрывать в скорости как при доступе, так и при записи. Хотя бы потому, что при обращении к ArrayList у вас лишний вызов метода, а может и не один. С другой стороны, внутри ArrayList'а тот же самый массив и доступ вполняется по тому же принципу, поэтому если нет чрезмерной нагрузки на него, то в общем их производительность примерно одного порядка. Разница для вас в том, что с листами работать намного проще и удобнее, чем с массивами. По этой причине вам не следует заниматься ерундой и гонять какие-то нелепые тесты, а просто использовать ArrayList, если только у вас нет каких-то ОЧЕНЬ серьёзных оснований использовать массив. Одно из таких оснований: вы точно знаете заранее размер массива и вы точно знаете, что использование этого массива в коде ограничено и вам не придётся городить огород, чтобы гонять потом эти массивы в листы и наоборот. UPD Что за числа в вашем тесте детские? 1000.000? Это просто смешно. Я прогнал тест на выполнение 10.000.000.000 добавлений и получил вот что: primitive array: 78896 ms array list: 132532 ms Второй прогон primitive array: 76832 ms array list: 124047 ms Исходный код теста здесь . Как видно, массив почти вдвое быстрее списка и никакой инлайнинг, рантайм-оптимизации не помогли, хотя, казалось бы, на большом интервале вркемени эти все оптимизации должны были бы сработать и время могло бы выровняться. Но нет. UPD2 Убрал сборку мусора вообще и перегруппировал нули и получил следующее primitive array: 26177 ms array list: 54482 ms Результат очень стабилен. Думаю, на get результаты будут подобные. UPD3 Кстати, вот показательный пример для любителей вызывать руками System.gc: как видно, частая ненужная сборка мусора приводит к двухкратному снижению производительности в данном тесте.

Доступ к private методам

Как получить доступ к private методу? C#, VS 2012. Спасибо. P.S. Прежнее название темы - "Unit Test для private методов"


Ответ

Решение - использовать Reflection например так: var field = typeof(CopyItems).GetMethod(("FixRenamedPath"), BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
string targetFile = (string)field.Invoke(null, new object[] { renamedFile, relatedFile, targetDir });

Не простые вопросы о языке C#

Был на собеседовании и завалился. Теперь пытаюсь постепенно забить пробелы в знаниях - осталось немного вопросов, которые я не могу решить сам, поэтому прошу помощи: Есть запакованная структура, как изменить значение поля структуры, при этом не распаковывая её? UPD1: Вопрос на собеседовании который я тоже к сожалению завалил и не смог найти адекватного ответа за пару дней, может кто либо из вас знает : Есть метод в котором много строк кода (100 например), в конце выполнения метода выбивает исключение, как сохранить те данные (ту работу которую проделал данный метод) до исключения ? Буду признателен если хотя бы дадите совет куда "копать" !


Ответ

Через интерфейс void Main() { var o = (I)new A(); (o).Inc(); (o).Dump(); }
interface I { void Inc(); }
struct A : I { public int f; public void Inc() { f++; } } выведет f = 1. Код (нету unbox): IL_0001: ldloca.s 01 // CS$0$0000 IL_0003: initobj UserQuery.A IL_0009: ldloc.1 // CS$0$0000 IL_000A: box UserQuery.A IL_000F: stloc.0 // o IL_0010: ldloc.0 // o IL_0011: callvirt UserQuery+I.Inc IL_0016: nop IL_0017: ldloc.0 // o IL_0018: call LINQPad.Extensions.Dump

Как “обрезать” ту часть изображения, которая является пустой?

Добрый день друзья! Я пишу сайт с нуля, сейчас закончил рисовать дизайн, но вот возникла проблема, взгляните на картинку

Красным пунктирным прямоугольником я выделил границы картинки с коленкой девушки, и всё дело в том, что границы картинки заползают на кнопку и потому в этом месте нажатие по кнопке невозможно будет сделать. Вопрос : можно ли как-то программно "обрезать" нижнюю часть картинки и по бокам, дабы пустое место на картинке не являлось его частью и можно было нажать на кнопку?
У меня уже был вариант - коленку девушки поместить на задний план, а кнопку на передний и обрезать часть картинки, которую занимает коленка у девушки. Но это на крайняк.


Ответ

Вот вам ещё способ: http://jsfiddle.net/Q3RSR/1/
.navbar-nav { margin-top: 0; margin-bottom: 0; } .navbar-nav > li { float: left; } .navbar-default .navbar-nav > li > a:hover { background: yellow; } .girl { position: relative; } .girl img { display: block; } .gp { position: absolute; z-index: 16; } #gp1 { bottom: -2px; left: 203px; } #gp2 { bottom: -4px; left: 204px; } #gp3 { bottom: -6px; left: 205px; } #gp4 { bottom: -8px; left: 208px; } #gp5 { bottom: -10px; left: 214px; } #gp6 { bottom: -12px; left: 218px; }


Он ужасен чуть более, чем полностью :) Но задачу решает, притом никак не затрагивая саму менюшку. Кликабельность кнопки при этом плавно обходит коленку.
А менюшку затрагивать не стоит, поскольку её вероятнее всего впоследствии будут редактировать люди, недостаточно компетентные в разработке сайтов, чтобы прописывать массивы значений для тэга . Да и даже самому разработчику не придётся этого делать, если пункты меню изменятся, и расположение кнопки по отношению к картинке изменится. Кроссбраузерность тоже имеет значение: ширина пунктов меню (а следовательно и положение данного пункта относительно картинки) может зависеть от шрифтов, которые как минимум в каждой ОС свои.
Порастягивайте вширь окно браузера: положение коленки относительно менюшки будет меняться, но работать корректно будет при любом положении.

Требуется найти последнюю цифру n-го числа Фибоначчи. Оптимизация алгоритма

Есть задача "Требуется найти последнюю цифру n-го числа Фибоначчи." по адресу http://acmp.ru/?main=task&id_task=623
Мое решение такое ( не знаю насколько этично выкладывать код решения в паблик )
#include #include
using namespace std;
int main(){ int a=1, b=1, c=a+b, n; cin >> n; if (n <= 1) c = 1; else for (int i = 2; i <= n; i++){ c = (a + b) % 10; a = b; b = c; } cout << c % 10; return 0; }
Результат: Время выполнения 0,858 Память 772 Кб
Согласно таблице на странице http://acmp.ru/index.asp?main=bstatus&id_t=623&lang=CPP за счет небольшого увеличения расхода памяти как то умудряются вложиться в 1-2 секунды. С одной стороны может быть мне подсунули входное число 1000, а другим 10.
Есть идеи по повышению производительности?


Ответ

Цитата из википедии
Период чисел Фибоначчи по модулю натурального числа n называется периодом Пизано и обозначается π(n). Периоды Пизано π(n) образуют последовательность: 1, 3, 8, 6, 20, 24, 16, 12, 24, 60, 10, 24, 28, 48, 40, 24, 36, … (последовательность A001175 в OEIS) В частности, последние цифры чисел Фибоначчи образуют периодическую последовательность с периодом π(10)=60, последняя пара цифр чисел Фибоначчи образует последовательность с периодом π(100)=300, последние три цифры — с периодом π(1000)=1500, последние четыре — с периодом π(10000)=15000, последние пять — с периодом π(100000)=150000 и т. д.
Что такое период Пизано понятно из таблицы для π(4):
n | 1 2 3 4 5 6 | 7 8 9 ... F(n) | 0 1 1 2 3 5 | 8 13 21 ... F(n) mod 4 | 0 1 1 2 3 1 | 0 1 1 ...
То есть π(4) = 6, а именно: остатки от деления чисел Фибоначчи на 4 повторяются с периодом 6.
Как это применить для решения задачи подумайте сами.

Следует ли коммитить в git промежуточные копии когда библиотека вообще не готова

Я так понимаю система git служит для контроля версий библиотеки и т.п.
Но если стоит иная задача: промежуточные копии когда библиотека вообще не готова. Например, добавил класс, в нём несколько функций. Библиотека не готова, она не рабочая, но мне нужно сделать точку восстановления. (Скажем, я не уверен точно каким путём идти дальше, чтобы можно было вернуться к этому состоянию, или же просто резервная копия случай сбоя). Коммит делать, как мне кажется нецелесообразно, существуют ли другие пути для этой задачи?


Ответ

Мой вариант работы - репозиторий лежит в интернете, работаю с нескольких мест. Коммиты до пуша хранятся локально, поэтому они больше для истории. Пуш в репозиторий в тестовую ветку в любом состоянии - чтобы при продолжении с другого места было доступно текущее состояние. В любом случае благодаря истории коммитов всегда можно вернуться на любой этап.
Но при этом вся разработка ведется в отдельной ветке, перед заливкой на боевой сервер рабочей версии - слияние с мастером, перед итоговым пушем в репозиторий дополнительный тест.
Правильная идеология - завести ветку testing, в которую коммит без ограничений, пуш по настроению, но слияние с мастером только работоспособной версии.
На возможной развилке можно создать новую ветку, потом победивший вариант вливается в testing, тестируется и уходит в мастер.
И как написал предыдущий докладчик - использовать тэги для отдельных вех.

Передача в функцию указателя или ссылки [дубликат]

На данный вопрос уже ответили: Чем отличаются ссылки от указателей в С++ 2 ответа В чем будет разница, если в функцию передать указатель и ссылку? например
#include void func(int *a) { *a = 5 } int main() { int a; func(a); std::cout << a; }
и
#include void func(int &a) { a = 5 } int main() { int a; func(a); std::cout << a; }
Программы выведут одно и то же? Ведь и так, и так мы обращаемся к существующему элементу, а не создаем новый.


Ответ

В принципе, технически разница между указателем и ссылкой лишь в том, что саму ссылку нельзя изменить (а указатель можно). [Вот тут бóльший список отличий.] Кроме этого, разница ещё синтаксическая: с ссылкой вы обращаетесь как будто это переменная, а с указателем нужно его правильно получать/разыменовывать:
void func(int *a) { *a = 5; } int main() { int a; func(&a); cout << a; }
Других технических отличий нет, и результат будет одинаковый.
Но разница на самом деле не в синтаксисе, а в смысле, в семантике.
Указатель может означать всё, что угодно. Он в C и C++ означает строку, ассив, адрес переменной, передачу переменной по ссылке и ещё кучу всяких вещей. А смысл ссылки ровно один — это как бы альтернативное имя (alias) существующей переменной.
Поэтому для случаев наподобие того, который вы описали, в C++ уместно использовать ссылку, а не указатель. Хотя, как вы сами видите, с указателем тоже прекрасно работает.
И ещё: в чистом C ссылок нет, так что у вас нет другого варианта кроме указателей.

Зачем нужен typedef?

В чем разница между
typedef struct LINE { .... };
и
struct LINE { ... };


Ответ

В Вашем примере разницы нет никакой, typedef просто игнорируется. Если же переписать этот код немного:
typedef struct LINE {
} alias;
То объект структуры можно будет создавать как с помощью LINE так и alias, т.к. typedef создаёт псевдонимы типов.

Чем отличается логическое ИЛИ от исключающее ИЛИ?

Не могу понять чем отличается логическое ИЛИ от исключающее ИЛИ?


Ответ

В целом это можно описать следующими таблицами истинности:
Таблица истинности для логического ИЛИ: ABA or B 00  0    01  1    10  1    11  1   
Таблица истинности для исключающего ИЛИ: ABA xor B 00   0    01   1    10   1    11   0   
Если на пальцах объяснять, то логическое ИЛИ будет истиной, когда хотя бы один из операндов — истина. Исключающее ИЛИ будет истиной, если операнды не равны, и ложью, если операнды равны.

Упростить код до 5 строк

Можно ли упростить этот код до 5 строк (вопрос из собеседования на позицию senior javascript developer)?:
function func(s, a, b) { var match_empty=/^$/ ; if (s.match(match_empty)) { return -1; } else { var i=s.length-1; var aIndex=-1; var bIndex=-1; while ((aIndex==-1) && (bIndex==-1) && (i>=0)) { if (s.substring(i, i+1) == a) aIndex=i; if (s.substring(i, i+1) == b) bIndex=i; i--; } if (aIndex != -1) { if (bIndex == -1) return aIndex; else return Math.max(aIndex, bIndex); } else { if (bIndex != -1) return bIndex; else return -1; } } };


Ответ

Навскидку, вроде бы, вот так можно «упростить»:
function func(s, a, b) { return Math.max( s.lastIndexOf(a), s.lastIndexOf(b)); }
Но это не правильно обработает случаи с пустыми строками в a или b. Поэтому:
upd. с тестами
function funcSergiks(s, a, b) { return Math.max( (a.length ? s.lastIndexOf(a) : -1), (b.length ? s.lastIndexOf(b) : -1) ) } // --------------------------------------- function func(s, a, b) { var match_empty = /^$/; if (s.match(match_empty)) { return -1; } else { var i = s.length - 1; var aIndex = -1; var bIndex = -1; while ((aIndex == -1) && (bIndex == -1) && (i >= 0)) { if (s.substring(i, i + 1) == a) aIndex = i; if (s.substring(i, i + 1) == b) bIndex = i; i--; } if (aIndex != -1) { if (bIndex == -1) return aIndex; else return Math.max(aIndex, bIndex); } else { if (bIndex != -1) return bIndex; else return -1; } } }; var tests = [ [ ['google', 'g', 'o'], 3 ], [ ['aba', 'a', 'b'], 2 ], [ ['', 'g', 'o'], -1 ], [ ['google', 'x', 'o'], 2 ], [ ['aba', '', ''], -1 ], [ ['aba', 'a', ''], 2 ], [ ['aba', '', 'b'], 1 ], [ ['aba', 'a', 'b'], 2 ], ]; tests.forEach(test => { var a = func.apply(this, test[0]); var b = funcSergiks.apply(this, test[0]); console.log(a == b && b == test[1] ? "PASSED" : "FAILED", JSON.stringify(test), a, b); });

Нормализация базы данных из 4 таблиц

Всем привет. Как правильно связать левую таблицу с группой из 3ех таблиц справа? Только вот получается связать методом представленным на 2ом изображении
Например, пользователь выбирает конкретную марку, модель и поколение автомобиля, и его выбор (марка, модель, поколение) требуется записать в другую таблицу.
create table CarBrend( [BrendID] int identity (0,1) not null, [Title] nvarchar(max) not null, constraint PK_BrendID primary key ([BrendID]) )
create table CarModel( [ModelID] int identity (0,1) not null, [BrendID] int not null foreign key references CarBrend([BrendID]), [Title] nvarchar(max) not null, constraint PK_ModelID primary key ([ModelID]) )
create table CarGeneration( [GenerationID] int identity (0,1) not null, [ModelID] int not null foreign key references CarModel([ModelID]), [Title] nvarchar(max) not null, [StartProduction] date not null, [EndProduction] date not null, constraint PK_GenerationID primary key ([GenerationID]) )
create table Car( [CarID] int identity (0,1) not null, [BrendID] int not null foreign key references CarBrend([BrendID]), [ModelID] int not null foreign key references CarModel([ModelID]), [GenerationID] int not null foreign key references CarGeneration([GenerationID]), constraint PK_CarID primary key ([CarID]), )
Я сомневаюсь в правильности 4ой таблицы (Car). Подскажите, как правильно поступить в данном случае.
В первой таблице CarBrend содержится марка автомобиля Nissan (и другие марки). В второй таблице CarModel содержится модель Primera марки Nissan (и другие модели). В третьей таблице CarGeneration содержаться все поколения Nissan'а Primer'ы - P10, P11-120, P11-140, P12 (и других). А в таблице Car(4) объединяются записи со всех 3х предыдущих таблиц (чтобы сформировать полную машину).


Ответ

БД не должна позволять внести в себя противоречивые данные. Это основной принцип проектирования. Второй предложенный вами способ, т.е с тремя полями у машины, позволяет создать одну машину бренда Мерседес и конкретной модели Mercedes W140 и другую машину, так же модель Mercedes W140, но поставить ей бренд Жигули. Значит такая БД сама напрашивается на внесение в нее некорректных данных.
Второй принцип проектирования - простота изменения одной сущности. предположим мы ошиблись и отнесли модель W140 к бренду жигули. создали несколько таких машин, спохватились и решили исправить бренд. В первом случае нам надо только менять бренд у конкретной модели. А во втором еще и пробежаться по всем машинам и поменять бренд у них.
Если посмотреть теорию проектирования, то второй вариант, с тремя ссылками, нарушает третью нормальную форму
Следовательно у машины должна быть только ссылка на ревизию модели и более ни на что. это позволит как избежать внесения несогласованных данных так и обеспечит принцип изменения одной сущности в одной таблице. Так что верна ваша первая картинка.

Как работает функция fork() в C. Не могу понять результат работы программы

У меня есть вот такой короткий пример кода, нам его дали что бы продемонстрировать работу функции fork():
#include #include #include #include int main () {
pid_t pid; pid = fork(); pid = fork();
printf("Fork-Test
");
return EXIT_SUCCESS; }
Мне не совсем понятен результат. В итоге у меня 4 раза в терминале пишет Fork-Test Не понимаю, во-первых почему это происходит больше одного раза, ведь я вызваю метод printf("Fork-Test
"); только один раз, во-вторых, раз уже несколько раз, то почему именно 4? При чем еще и в следующем виде:
Fork-Test Fork-Test
Process returned 0 (0x0) execution time : 0.007 s Press ENTER to continue Fork-Test Fork-Test
смысл мне не понятен. буду благодарна за любые пояснения по поводу fork()


Ответ

Процесс после системного вызова fork, раздваивается, у исходного процесса создаётся идентичный потомок-двойник в идентичном состоянии (ну почти). Создавшийся процесс будет занят выполнением того же кода ровно с той же точки, что и исходный процесс.
Различить кто создал, а кто создался, можно по возвращаемому значению fork, поэтому его результат обычно передаётся в if, чтобы эти процессы выполнили какие-то разные вещи, один пошёл в ветку if, другой в ветку else
Вы же возвращаемое значение игнорируете (сохраняете, но никак не используете), и потому оба процесса продолжают идти по одному и тому же пути. И натыкаются на ещё один вызов fork. И каждый из них раздваивается снова. Получается следующая картина:
P # перед первым pid = fork();
[fork 1]
P # перед вторым pid = fork(); \ P(1) # перед вторым pid = fork();
[fork 2]
P # перед printf("Fork-Test
"); / \ P(2) P(1) # перед printf("Fork-Test
"); # перед printf("Fork-Test
"); \ P(1)(2) # перед printf("Fork-Test
");
После второго форка процессов уже 4. И после этих форков каждый процесс доходит до вызова printf и выводит указанную строку. Каждый процесс делает это сам. Поэтому вывод происходит столько раз, сколько вышло процессов.
Можете убедиться в этом, поместив вывод перед вторым форком (вывод произойдёт дважды) или перед первым (единожды).
Завершаются они независимо друг от друга. У вас получилось, что процесс P завершился вторым. А нечто, через что вы запускали этот процесс, следило только за процессом P, но не его "клонами" (т. к. у них собственные pid, process ID), поэтому для остальных такого вывода нет.

Последняя итерация foreach

Можно ли узнать, используя foreach, что текущая итерация последняя?


Ответ

Самый простой способ - добавить переменную с инкрементом на каждой итерации и проверять её соответствие свойству Count контейнера. Однако в этом случае цикл foreach фактически превращается в обычный for
При этом foreach заточен на прогон по всем элементам и выполнения одинаковых действий вне зависимости от позиции элемента. Если подобный вопрос у Вас возник, то значит что-то не так с дизайном. Лучше использовать обычный for

О чем должен говорить комментарий в коде?

О чем должен говорить комментарий в коде? О том, что происходит в следующем блоке кода или о том, что должно произойти в результате выполнения этого блока кода? Что в этом вопросе подсказывает/требует практика?


Ответ

Хороший комментарий — ненаписанный комментарий. Следует стремиться писать код так, чтобы комментарии были просто не нужны.
Проблема комментариев в том, что
часто они находятся в одном месте, а помнить о них их нужно в другом компилятор не может проверить истинность комментария, поэтому при изменении кода комментарий устаревает
Пройдёмся по часто встречающимся случаям, в которых комментарии излишни.
Если вы хотите прокомментировать, для чего нужна какая-то переменная, выбросьте комментарий, и измените имя переменной на более подходящее.
int n; // количество страусов
лучше заменить на
int numberOfOstriches; Если вы хотите сообщить, что выполняется какое-то условие, лучше поставить assert
// тут pBFG не может быть nullptr-ом, проверка не нужна pBFG->fire();
лучше заменить на
assert(pBFG); pBFG->fire(); Если вы описываете в комментарии, что именно делает кусок кода, имеет смысл вместо этого выделить этот кусок в отдельную функцию, а смысл кода сделать её именем.
// нормализовать вектор скорости double temp_length = sqrt(velocity.x * velocity.x + velocity.y * velocity.y); velocity.x /= temp_length; velocity.y /= temp_length;
лучше заменить на
void Normalize(vector& v) { double length = sqrt(v.x * v.x + v.y * v.y); if (length == 0.0) throw argument_exception("zero length vector"); v.x /= length; v.y /= length; }

Normalize(velocity); Если вы описываете в комментарии самоочевидные вещи, лучше этот комментарий просто выкинуть.
// этот класс представляет точку class Point { public int X; // координата X public int Y; // координата Y }
ни капли не теряет в читаемости в таком виде:
class Point { public int X; public int Y; }
(а если бессмысленные комментарии требуются от вас стандартами кодирования, потребуйте изменения этих стандартов!)
Таким образом, что происходит в участке кода, должно быть по возможности понятно из самого куска кода. Если это не так — улучшайте его.
Если комментарий представляет собой на деле документацию к вашему коду, тут ничего не поделаешь, удалять его не нужно.

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

Как исправить ошибку GIT

Ошибка:
$ git push form1 master To https://github.com/prochka/form-captchaNumber-ajax ! [rejected] master -> master (fetch first) error: failed to push some refs to 'https://github.com/prochka/form-captchaNumber-ajax' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Репозиторий на GitHub был только что создан и там нет никаких изменений


Ответ

У вас есть там изменения, которых нет в локальном репозитории. Вы сделали не пустой репозиторий на Github, а с начальным коммитом. У локального репозитория свой первый коммит и эти коммиты, как вы понимаете, не равны (фактические у вас просто два разных репозитория).
Просто удалите папку .git локально, создайте репозиторий (git init) заново, пропишите upstream (git remote add ...) и после этого можно делать git pull. Должно помочь :)

Как перехватить исключение любого типа в C#

Как перехватить исключение любого типа в C#


Ответ

Необходимо использовать следующую схему кода try { // Блок кода, где генерируется исключение } catch (Exception e) { // Выполняем обработку исключительной ситуации }

Каким образом рисуется кружок с помощью javascript?

Интересует не код, а алгоритм, ход решения. Также интересно, как нарисовать градиент выбора цвета на js.


Ответ

Итак, техника рисования ромбиков на js (для рисования кружков нужно взять функцию полукруга, но идея точно такая же): var obj = document.getElementById('container'); var tmp, k = 0, m = 100; for (var i = 0; i < m; i++) { if (i > m / 2) k--; else k++; tmp = document.createElement('div'); tmp.width = k + 'px'; tmp.height = '1px'; obj.appendChild(tmp); } А вообще все верно Вам намекают на использование canvas, т.к. под IE есть поддержка от гугла, а в адекватных браузерах он и так работает на ура.

Анализ изображения

Необходимо проанализировав изображение, сообщить количество и местоположение ЛИЦ человеков в этом изображении. Нужен как можно более эффективный и корректный алгоритм. Кто подскажет с чего начать?


Ответ

Задачка несложная и все это уже давным-давно реализовано в библиотеке OpenCV, у которой есть полностью работоспособный биндинг к C# под названием EmguCV.
Список реализованных алгоритмов можно найти здесь, а пример использования на (правда, на Java, но суть от этого не меняется) - тут.

Если хочется попробовать что-то свое, да еще и небесполезное, то можете попробовать изучить и реализовать другие алгоритмы с референсами, насколько мне известно, существует несколько интересных статей, датированных 2011 годом.
Несколько интересных референсов по теме, которые я сам в свое время изучал:
Cao, Z., Yin, Q., Tang, X., Sun, J.: Face recognition with learning based descriptor. CVPR (2010) Karl B. J. Axnick, Kim C. N: Fast Face Recognition Ion Marques - Face Recognition Algorithms (2010)
Последняя статья носит роль более-менее современного обзора всех популярных алгоритмов и интересна в первую очередь списком из 125 ссылок на другие работы.

“Идеальный код” или “Совершенный код” [закрыт]

Привет всем! На каникулы решил закупить книги по программированию. В процессе поиска "Совершенного кода" нашёл книгу "Идеальный код" Энди Орама (редактор серии O'Reilly) и Грегори Уилсона. Как вам эта книга по сравнению с "Совершенным кодом" ?


Ответ

Даже судя по оглавлению, "Идеальный код" -- простой сборник статей(примеров) из журналов. Сам недавно дочитал "Совершенный код", очень рекомендую сначала прочитать его.

Как скрыть номер телефона от поисковиков.

noindex - это только для Яндекса. Есть ли какой-нибудь универсальный метод?


Ответ

Картинки индексируются не менее хорошо чем текст. Можно сделать асинхронно подгружаемым автоматически или по требованию пользователя (клику). То есть, после загрузки страницы, запускаем ajax запрос на получение номера телефона. Также можно поставить дополнительные проверки в самом js и на стороне сервера. Сам код элементарен. В качестве примера: // client $(function(){ $('#phone').load('/get_phone.php'); });
// server function isBot() {
if ( !(isset($_COOKIE['какая-нибудь-кука']) && isset($_SERVER['HTTP_USER_AGENT'])) ) return true;
return preg_match("/(bot|slurp|mail\.ru)/i", $_SERVER['HTTP_USER_AGENT']); }
echo isBot()? '':'+7 (495) 224-22-22'; UPD: @sergiks напомнил ещё один вариант. Обфусцировать номера телефонов и добавлять их на страницу посредством того же js включённого в саму страницу.

Как написать сайт на Python без использования фреймворков? [закрыт]

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


Ответ

Обычно используют какой-нибудь web-фреймворк http://wiki.python.org/moin/WebFrameworks Рекомендую начать с Django from wsgiref import simple_server
def app(environ, start_response): start_response('200 OK', [('Content-type', 'text/plain')]) return ['Hello world!']
server = simple_server.WSGIServer(('', 8000), simple_server.WSGIRequestHandler) server.set_app(app) server.serve_forever() Вот простейший код, отдающий HTML страницу по http://127.0.0.1:8000 Но не стоит городить велосипед. Есть огромное количество легких фреймворков, от которых можно использовать только нужные компоненты - роутинг, шаблонизатор итд.

Как удалить все HTML-теги регулярным выражением?

Есть регулярное выражение (\<(/?[^>]+)>), которое оставляет HTML-тэги. Как наоборот удалить все тэги, оставив только текст?


Ответ

Так собственно её и можно использовать для чистки тегов, скормив в sub
В Python:
>>> import re >>> re.sub(r'(\<(/?[^>]+)>)', '', 'Текст с
тегами
') 'Текст с тегами'
В JavaScript:
>>> console.log('Текст с
тегами
'.replace(/(\<(\/?[^>]+)>)/g, '')) "Текст с тегами"
Только надо обязательно помнить, что никакое регулярное выражение не сможет правильно обработать сломанный html:
>>> line = '

>>>2 + 3 < 6
True
>> re.sub(r'(\<(/?[^>]+)>)', '', line) ' >>>2 + 3 True тарий -->И для такого дела лучше применять полноценные html-парсеры, а регулярки к html-коду не подпускать вообще