Страницы

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

пятница, 9 ноября 2018 г.

Как убрать заголовок диалога

Как вызвать что-нибудь диалоговое без ActionBar, чтобы высвечивался только layout файл. Варианты со скрытием\убийством ActionBar\изменением темы Activity``DialogFragment`` (если можно) тоже подойдут.
Попытки, которые я пробовал, но ничего не вышло:
Сделать Activity с темами @android:style/Theme.Dialog.NoTitleBar и @android:style/Theme.NoTitleBar.Dialog Сделать Activity с темами @android:style/Theme.Dialog.NoTitleBar и @android:style/Theme.NoTitleBar.Dialog. Сделать DialogFragment, а потом убрать, скрыть ActionBar — оказывается у DialogFragment нет ActionBar (по крайней мере, getActionBar не рработает). Сделать свой style с Dialog и NoTitleBar. Тут совсем ничего не вышло.
Помогите, пожалуйста!


Ответ

Вот один из вариантов решения Вашей задачи:
Если используете Dialog
Dialog dialog = new Dialog(context); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.my_dialog_la); dialog.show(); Если расширяете DialogFragment, то в onCreate добавьте следующую строку:
setStyle(STYLE_NO_TITLE, 0);

Как правильно организовать REST-клиент ? Асинхронная загрузка JSON, изображений в базу и отображении в списке

Хочу разобраться разобраться как правильно организовать REST-клиент.
Есть API, которая по запросу выдает JSON объекты.
Нужно построить список ListView(или лучше использовать RecyclerView?) из этих JSON.
Как я это все делаю:
public class MainActivity extends AppCompatActivity {
private static final String API = "https://api.github.com";
ListView listView; UserAdapter adapter; DBHandler mDBhandler;
int lastUserIDinList=0; //начальное кол-во пользователей в списке int initialAmountUsers=10;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
mDBhandler = new DBHandler(this);
listView = (ListView) findViewById(R.id.listview);
adapter = new UserAdapter(MainActivity.this, new ArrayList()); listView.setAdapter(adapter);
new CountUserInDB().execute();
listView.setOnScrollListener(new EndlessScrollListener() { @Override public boolean onLoadMore(int page, int totalItemsCount) { loadUsers(1); return true; } });
}
//получаем от API объекты, ждем коллбэк и запускаем AsyncTask запись в базу(в качестве параметра передаем список моделей) void loadUsers(int count){ RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(API).build(); GitAPI git = restAdapter.create(GitAPI.class); //полчаем от АПИ пользователей с ид больше lastUserIDinList. количество пользователей в ответе - count git.getNextUsers(lastUserIDinList, count, new Callback>() { @Override public void success(ArrayList gitHubUsers, Response response) { new WriteToDB().execute(gitHubUsers); }
@Override public void failure(RetrofitError error) { Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show(); } }); }

//get arralist of users and write it to db class WriteToDB extends AsyncTask,Void,Integer> {
@Override protected void onPreExecute() { super.onPreExecute(); }
@Override protected Integer doInBackground(ArrayList... params) { //заноси в таблицу всех пользователей полученных в коллбэке for(int i=0; i @Override protected void onPostExecute(Integer firstID) { super.onPostExecute(firstID); //вызываем четние из базы с первого ид, который пришел в ответе от АПИ new ReadFromDB().execute(firstID); } }
//get id of userd from what need to read from db class ReadFromDB extends AsyncTask> {
@Override protected void onPreExecute() { super.onPreExecute(); }
@Override protected ArrayList doInBackground(Integer... params) { //читаем из базы всех пользователей, ид которых >= params[0] return mDBhandler.getUserFromID(params[0]); }
@Override protected void onPostExecute(ArrayList userList) { super.onPostExecute(userList); new DisplayUserInListView().execute(userList); } }

//get arralist of users and add it to adapter class DisplayUserInListView extends AsyncTask,Void,Void> { @Override protected void onPreExecute() { super.onPreExecute(); }
@Override protected Void doInBackground(ArrayList... params) { //добавляем по очереди пользователей в адаптер for(int i=0; i @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); //сообщаем, что обновили данные adapter.notifyDataSetChanged(); } }

class CountUserInDB extends AsyncTask {
int lastUserIDinTable=-1;
@Override protected void onPreExecute() { super.onPreExecute(); }
@Override protected Integer doInBackground(Void... params) { //получаем ИД последней записи в таблице lastUserIDinTable=mDBhandler.getLastUseID(); //получаем количество пользователей в таблице return mDBhandler.getUserCount(); }
@Override protected void onPostExecute(Integer userCount) { super.onPostExecute(userCount);
if(userCount==0){ //база пуста, загрузим 10 пользователей для начала loadUsers(10); }
if(userCount>=initialAmountUsers){ //в базе больше 10 пользователей, что достаточно для начала - читаем из базы. new ReadFromDB().execute(0); }
if(userCount>0 && userCount }
} }


}
У меня такое чувство, что сделал какой-то велосипед.
Какие есть советы по улучшение(или переделыванию полностью) логики ? Не много ли я использую AsyncTask ?
Интересны любые советы по грамотному получению JSON объектов, использованию API, добавлением итемов в список..
UPD:
Почитав статьи, пришел к выводу, что REST клиента на андроиде нужно делать по двум вариантам:
1)Создавать сервис, в котором будут загружаться данные с API(), парситься, записываться в базу и потом передавать в активити сообщение, что надо обновить список. Активити как получит такое уведомление, с помощью CursorLoader'а грузит данные из таблицы и добавляет их адаптеру списка.
2)Не создавать сервисов, а в активити с помощью AsyncTaskLoader'ов(для получения инфы в фоне, при этом еще использовать Retrofit) и CursorLoader'ов, с помощью которых читать/писать базу.
Какой из этих подходов более грамотный ? Возможно есть какие-то дополнения или уточнения к этим подходам ?


Ответ

Многократно уже отписывался на эту тему, как писать REST клиента. Не поленюсь написать еще раз:
Через сервис тягаем JSON объекты из сети и складываем в SQLite БД Над SQLite БД создаем ContentProvider и через CursorLoader организуем подпитку CursorAdapter, который и будет адаптером для ListView или RecyclerView Вопрос выбора ListView или RecyclerView - это вопрос не только вкуса, но и квалификации (все таки). Как показывает опыт RecyclerView сложнее в понимании, но дает гораздо большую свободы в плане управления списком. Я бы рекомендовал начинать с ListView и только потом приступать к RecyclerView Для работы с JSon лучшим инструментом является Google Gson - берите его и даже не сомневайтесь. Функция Gson очень простая, но важная: это трансляция вашего Java объекта в Json строку и обратно. По сути вместо рутинного парсинга json строки вы будете иметь дело с интеллигентными Java классами. Часто при работе с Rest требуется реализация функциональности Pull-To-Refresh - ну то есть обновление списка при вытягивании вверх/вниз. В сети есть огромное количество реализаций Pull-To-Refresh. Я пользовался этим проектом - но он сейчас мертвый. Недавно в суппорт либах появился новый виджет: SwipeRefreshLayout я лично не пользовался не знаю как с ним работать. Те из знакомых кто пользовались - пищат от восторга. У меня нет оснований не доверять им.
P.S. Для RecyclerView организовать CursorAdapter напрямую не получится, нужно будет применить эту наработку
Update
Создавать сервис, в котором будут загружаться данные с API(), парситься, записываться в базу и потом передавать в активити сообщение, что надо обновить список. Активити как получит такое уведомление, с помощью CursorLoader'а грузит данные из таблицы и добавляет их адаптеру списка.
В качестве сервиса подойдет IntentService, который можно запускать по таймеру и/или через событие генерируемое при Pull-To-Refresh Не надо никак уведомлять Activity о том, что БД изменилось - CursorLoader сам будет автоматом подгружать обновленные данные при изменении БД через соответствующий Observer (в случае RecyclerView), а в случае CursorAdapter это уже будет "из коробки"

Префиксы в именах полей БД

Как правильно называть поля в БД? Например, в таблице users назвать поля user_id, user_name и т.п. или просто id, name?


Ответ

Никаких авторитетных источников не знаю, но по своему опыту работы с фреймворками и CMS'ками могу сказать, что нет смысла префикса в полях, так как они уже принадлежат таблице. Предположим, что у нас есть две таблицы: student и department, и мы попытаемся достать данные из двух таблиц:
SELECT student.student_name, department.department_name FROM student, department WHERE student.department_id = department.department_id
Или всe же лучше сделать так?
SELECT student.name, department.name FROM student, department WHERE student.department_id = department.id
Префикс поля в таблице нужен в том случае, если это ключ на другую таблицу, как, например, в моем случае: student.department_id

Как считать символ с мультибайтовой строки?

Есть мультибайтовая строка, длина её меряется в мегабайтах, нужно считывать в цикле посимвольно, как считать один символ с мультибайтовой строки?(не используя uchar.h)


Ответ

Берем очередной байт из строки. Предполагая, что это первый байт utf-8 символа
unsigned char b=...; // тут проверяемый байт (обязательно unsigned !!!) if(b<=0x7F) это однобайтовый символ, можем выдавать его и проверять следующий else if(b>=0xF8) ... это не unicode символ, или более новый стандарт с более чем 4х байтовыми символами else if(b>=0xF0) ... это 4х байтовый символ. т.е. берем еще следующие 3 байта else if(b>=0xE0) ... это 3х байтовый символ. т.е. берем еще следующие 2 байта else if(b>=0xC0) ... это 2х байтовый символ. т.е. берем еще следующий байт else ... b - совершенно точно один из серединных байт символа, мы потеряли первый байт
Если символ длиной более 1 байта, то все последующие байты символа должны быть в диапазоне b>=0x80 && b<0xC0
Написал по стандарту RFC3629, надеюсь нигде не ошибся. Можно еще посмотреть код готовых библиотек.
Эх. Обожаю делать велосипеды, вот накидал пример, с разбором кодов символов. Получаемые коды для русских букв сверил с выдаваемых функцией Javascript charCodeAt - совпали. Внимание: собрано на коленке. нет проверок, что строка закончилась в середине символа, при неправильной unicode строке возможен выход за пределы массива ! Трехбайтные и четырехбайтные символы так же не проверены, т.к. не знаю китайского. Так же нет проверки 2го и последующего байта unicode на корректность, тупо сбрасываем старшие 2 бита и используем.
#include #include
unsigned char *s="Test string. Тестовая строка"; int main() { int len=strlen(s); int i; int sim_code; // Сюда собираем код очередного символа for(i=0;i=0xF8) { printf("Не unicode 6.0 (RFC3629) символ %X",s[i]); continue; } else if(s[i]>=0xF0) { sim_code=( ((s[i]&0x07)<<18) | ((s[i+1]&0x3F)<<12) | ((s[i+2]&0x3F)<<6) | (s[i+3]&0x3F) ); i+=3; } else if(s[i]>=0xE0) { sim_code=( ((s[i]&0x0F)<<12) | ((s[i+1]&0x3F)<<6) | (s[i+2]&0x3F) ); i+=2; } else if(s[i]>=0xC0) { sim_code=( ((s[i]&0x1F)<<6) | (s[i+1] & 0x3F) ); i++; } else { printf("Пропущен первый байт unicode символа !!! (%X)",s[i]); continue; } printf("%d ",sim_code); } }
Универсальный способ получения длины текущего символа:
unsigned char b=s[i]; // Берем первый байт символа int n; // длина символа if(b<=0x7F) n=1; ... это однобайтовый символ, работаем с ним как есть else for(n=0; b & 0x80; n++) b<<=1; // после цикла n=полной длине в байтах, включая текущий байт

Сохранение элементов ListView после перезагрузки приложения

Есть приложение, в котором при нажатии на кнопку создаются и добавляются элементы списка ListView. При перезагрузке приложения, они пропадают. Догадываюсь, что нужно использовать БД, и при создании элемента добавлять его в БД, а в методе OnCreate поставить создание списка ListView из элементов в БД(исправьте, если я не прав). Вопрос такой: можно ли сохранять список после перезагрузки приложения НЕ ИСПОЛЬЗУЯ БД, т.к. в списке будет максимум 10-15 элеметов(это потолок). Б


Ответ

У Activity есть onSaveInstanceState, который срабатывает при закрытии. Переопределите его, чтоб сохранить данные из ListView
public void onSaveInstanceState(Bundle savedState) {
super.onSaveInstanceState(savedState);
// здесь берём данные из адаптера // если у вас ArrayAdapter, то будет так String[] values = mAdapter.getValues(); savedState.putStringArray("myKey", values);
}
А потом в onCreate получайте:
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) { String[] values = savedInstanceState.getStringArray("myKey"); if (values != null) { mAdaptor = new MyAdaptor(values); } }
[...]
}

Как узнать кто и когда добавил строку?

Есть файл A, в котором появилась определенная строка. Предположим: if(1 == 1){...}
Как с помощью SVN определить кто автор этой строки(чей коммит привнес эту строку) + номер ветки.


Ответ

То же доступно в TotroiseSVN: Клик правой по файлу в репозитории - Tortoise SVN -> Blame (опции на ваше усмотрение).
Кликнув правой по строке с автором, можно посмотреть лог и предыдущий Blame.

Откуда берется номер строки исключения в Java?

К примеру, наш исходный код выполняет деление на ноль в строке 8. Если собрать jar-файл из этого кода и запустить - ArithmeticException опять скажет нам про строку 8 в нашем исходнике.
Получается, что в .class-файлах сохраняется даже форматирование исходника (java)? Или тут какой-то другой механизм?


Ответ

При компиляции по умолчанию добавляется номер строки в получаемый byte-код
Можно настроить объем debug-информации, попадаемый в генерируемые файлы, с помощью параметра компилятора -g
-g:none Без отладочной информации. -g:lines Только номера строк. -g:lines,source Номера строк и информация об исходном файле. -g:lines,source,vars Номера строк, информация об исходном файле и данные о локальных переменных. -g То же самое, что и -g:lines,source,vars
Значение по умолчанию: -g:lines,source

Хранение параметров с разными типами данных в одной таблице

Есть набор параметров с разными типами данных. У каждого параметра есть имя, набор ещё каких-то свойств и само значение параметра. Эта значение параметра может быть разных типов в зависимости самого параметра.
Вопрос: Как организовать хранение значений этих параметров в одной таблице?
Варианты которые сразу пришли в голову:
Хранить значение параметра в типа varchar и сделать ещё один столбец с описанием типа. И в случае необходимости этого параметра в приложении конвертировать его в нужный тип. Таблица с параметрами выглядела бы примерно так:
id | name | value | value_type Сделать кучу полей на каждый существующий тип параметра. То есть таблица с параметрами выглядела бы примерно так:
id | name | value_varchar | value_int | value_bit | и так далее
Какие best practice есть для решения задачи такого рода?
Уточнение задачи:
Разумеется это будет две таблицы. Одна таблица-справочник с идентификатором и именем параметра, а другая таблица-связь параметра с другой сущностью. Параметров этих будет не много. Не много в рамках БД конечно. Не 2 миллиона. Использоваться это будет следующим образом: Будет хранимка которая получает набор параметров по идентификатору той самой другой сущности. И в приложении мне нужно их распарсить в плане типа и использовать. Если это какой-то размер, то конвертируем в int или double и применять. Если это какое-то название, то конвертируем в string и используем, и так далее.
Принятое решение: Использовать тип данных sql_variant


Ответ

В MS SQL Server, начиная с версии 2008, есть такой тип данных, как sql_variant. Это именно то, что нужно вам в вашей задаче.

Выразить побитовое и (a & b) через десятичную арифметку

Существует ли способ выразить операцию побитовое И через арифметические действия (+,-,*,/,** и проч.)?


Ответ

Да.
a & b = a0*b0 * 2^0 + a1*b1 * 2^1 + ... + aN * bN * 2^N
Где ai - i-й бит a, bi - i-й бит b

Подсчет количества вхождений букв в строку с помощью потока (Stream)

Есть определенная строка(например "Some example"). Нужно определить количество вхождений каждой буквы в строке с помощью потока Stream и при этом без использования циклов, if и прочего(лишь рекурсия, потоки Stream и его методы вроде map, reduce, filter).
Я сделал из строки массив символов, который потом превратил в список c помощью рекурсивного метода toCharList.
String text = "Some example".toLowerCase.replaceAll("\\s", "") List textInChar = toCharList(text.toCharArray(), 0);
static public List toCharList(char[] textChars, int i) {
if(textChars.length == i) return new ArrayList<>();
List ret = new ArrayList<>(); ret.add(textChars[i]); ret.addAll(toCharList(textChars, i + 1));
return ret; }
Затем из этого списка создал хэш-мапу c помощью перегруженного метода toCharMap. Таким образом получил я список всех не повторяющихся букв, которые есть в строке.
Map countChar = toCharMap(textInChar);
public static Map toCharMap(List l) { return toCharMap(l.iterator()); }
public static Map toCharMap(Iterator it) { if (!it.hasNext()) return new HashMap<>();
Map ret = new HashMap<>(); ret.put((Character)it.next(), 0); ret.putAll(toCharMap(it));
return ret; }
Но как теперь их посчитать в потоке, например с помощью filter и reduce?


Ответ

1) Из строки массив символов лучше получать так:
String text = ("Some example").toLowerCase().replaceAll("\\s", ""); List textInChar = Chars.asList(text.toCharArray());
или:
textInChar = text.chars().mapToObj(e->(char)e).collect(Collectors.toList());
2) Xэш-мапу не повторяющихся символов лучше получить тогда уж так:
Map countChar = textInChar.stream().collect(HashMap::new, (m, c) -> { m.put(c, 1); m.put(c, 1); }, HashMap::putAll);
А всю задачу я бы решил так:
textInChar = text.chars().mapToObj(e->(char)e).collect(Collectors.toList()); Map countChar = textInChar.stream().collect(HashMap::new, (m, c) -> { if(m.containsKey(c)) m.put(c, m.get(c) + 1); else m.put(c, 1); }, HashMap::putAll);
Проверим:
countChar.forEach( (k, v) -> LOG.debug(k + " -> " + v));
Выведет:
p -> 1 a -> 1 s -> 1 e -> 3 x -> 1 l -> 1 m -> 2 o -> 1
UPD:
if(m.containsKey(c)) m.put(c, m.get(c) + 1); else m.put(c, 1);
Можно сократить до:
m.put(c, m.containsKey(c) ? (m.get(c) + 1) : 1);

Генератор случайных чисел std::mt19937 из всегда выдает одно и то же число

Здравствуйте. Мне нужно создать функцию, которая возвращала бы случайное число. Чуть ниже можно посмотреть, как я это пробовал реализовать. Ошибок нет, число есть, проблема в том, что число это всегда одно и тоже. Ну и как вы уже вероятно догадались, вопрос в том, как мне исправить данную ситуацию? Желательно с примером.
int TestClass::returnRandom(int max){ std::random_device randD; std::mt19937 randMT(randD()); std::uniform_int_distribution range(0, max); return range(randMT); }


Ответ

Проблема в том, что randMT каждый раз создается заново.
std::mt19937 - это генератор псевдослучайных чисел, для получения последовательности чисел его надо создать один раз, и потом использовать его вместе с каким-то случайным распределением чтобы получать случайные числа.
По этому его надо сделать членом класса:
class TestClass { public: TestClass() { std::random_device device; random_generator_.seed(device()); }
int returnRandom(int max) { std::uniform_int_distribution range(0, max); return range(random_generator_); }
private: std::mt19937 random_generator_; };
Если класс создается много раз и часто, то есть смысл создавать объект std::random_device не в конструкторе, а где-то еще, т.к. его создание тоже может быть медленной операцией.
Также объект std::mt19937 можно инициализировать текущим временем. Однако это слабый источник энтропии, потому что у текущего времени очень мало случайных бит.
auto now = std::chrono::high_resolution_clock::now(); random_generator_.seed(now.time_since_epoch().count());

От какого лица и в какой форме писать комментарии в документации на английском?

Допустим, я пишу комментарий к функции для документации. Мне нужно описать что она делает. Форматирование пока опустим. Предположим, это функция загрузки файла с сервера. По-русски я напишу что-то вроде этих вариантов:
/* * Функция загрузки файла * или * Загрузка файла */
Я слабо владею английским. В русском языке принято описывать алгоритм от третьего лица, но на английском часто встречал описание от второго лица. Как правильно написать такую функцию на английском? Нужно ли подразумевать 'it' и писать от третьего лица? Или вовсе писать в неопределенной форме? Сейчас я пишу так:
/* * Loads a file */


Ответ

Ваш вариант вполне хорош, он описывает что делает функция, как будто мы объясняем её кому-то используя только комментарии:
/* Loads a file */ /* Processes the queue */ /* Opens a remote resource */
Второй вариант, который я встречал, это описание того, что мы хотим сделать этой функцией:
/* Load a file */ /* Process the queue */ /* Open a remote resource */
Эти два варианта самые частовстречающиеся, используйте любой, который предпочитаете лично.

Различные варианты конфигурации приложения

Есть приложение с полной функциональностью. Это приложение для одного типа пользователей. Они могут редактировать/удалять/добавлять. Но есть и другие пользователи, которым это делать нельзя.
Каким путем пойти, что бы не создавать несколько похожих приложений, но с небольшими различиями по функционалу?
В Delphi я применял такой подход.
#IFDEF DISPATCHER ... #ENDIF
#IFDEF VIEWER ... #ENDIF
В VisualStudio почему-то так
#if DEBUG // Работает #endif
#if RELEASE // Не работает #endif


Ответ

Все дело в настройках проекта. Конфигурация Debug по умолчанию определяет символы DEBUG и TRACE, конфигурация же Release определяет только TRACE (символа RELEASE не существует).
Вам поможет вот такой способ:
#if !DEBUG
#endif
Или вот такой:
#if DEBUG
#else
#endif
Также в свойствах проекта вы можете определить свои символы для условной компиляции. У меня это делается вот так:

Но, вообще говоря, для разных режимов работы обычно хорошо подходят настройки и конфигурационные файлы:
if (Properties.Settings.Default.CanEditFoo) { // ... }
Также имеет смысл ограничить доступ пользователя на стороне сервера или СУБД. Если в организации используется Active Directory - то хорошим решением будет авторизация пользователей на основе доменных групп, к которым они относятся.

Дублирование имен файлов в проектах С++

Имею проект C++ под qmake с иерархической структурой TEMPLATE=SUBDIRS
Module1 ModuleStaticLib1 UnutTest1 Module2 ModuleStaticLib2 UnutTest2 Module3 Приложение
В каждом подпроекте могут быть *.cpp файлы с одинаковыми именами
Module1/ModuleStaticLib1/Controller.cpp - реализация класса namespace Module1::Controller UnitTest1/Controller.cpp - юнит тест класса Module1::Controller Module2/ModuleStaticLib2/Controller.cpp - реализация Module2::Controller UnitTest2/Controller.cpp - юнит тест класса Module2::Controller
Работаю в qtcreator. Обратил внимание на странный баг при отладке, если установить точку останова в UnitTest1/Controller.cpp, она ставится также и в Module1/ModuleStaticLib1/Controller.cpp (может и в другие одноименные файлы, но я гоняю один тест). В рамках одного модуля имена файлов не повторяются.
Кроме того мой коллега, выразил сомнение в таком подходе, могут быть проблемы со сборкой(я не замечал). На сколько корректно использование одинаковых имен в разных модулях, и чем может быть баг с точками оcтанова qtcreator или GDB?
QtCreator 3.5.81 gcc version 4.8.4 GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1 Linux Mint17
PS Демонстрация структуры "Глюкодрома" =)


Ответ

По-моему, опция "Set breakpoints using a full absolute path" решает проблему с дублированием точек останова.

Как вычесть массив из массива?

Есть 2 массива int[], содержащие элементы Drawable.
int[] m1 = new int[]{R.drawable.img1, R.drawable.img2, R.drawable.img3} int[] m2 = new int[]{R.drawable.img1, }
Необходимо найти разницу, те сравнить 2 массива и оставить только неповторяющиеся элементы.
Порядок не важен. Дублирование значений в массивах исключено. Изначально известно что М1 содержит 50 элементов М2, их только нужно оттуда убрать.
Долго не было ответа, решил вот так: Спасибо за помощь.
private int[] delArray(int[] a, int[] b) { List list_A = new ArrayList(); for (int index = 0; index < a.length; index++) { list_A.add(a[index]); } List list_B = new ArrayList(); for (int index = 0; index < b.length; index++) { list_B.add(b[index]); }
list_A.removeAll(list_B);
int[] ret = new int[list_A.size()]; for(int i = 0;i < ret.length;i++) ret[i] = list_A.get(i);
return ret; }


Ответ

Попробуйте так:
final int[] a1 = {12, 14, 15, 62, 12, 23}; final int[] a2 = {1, 12, 32, 23, 22}; List intList = new ArrayList() {{ for (int a : a1) add(a); }}; List intList_2 = new ArrayList() {{ for (int a : a2) add(a); }}; intList.removeAll(intList_2);
for (int a : intList) System.out.println(a);
Итог: 14, 15, 62

Как узнать регион пользователя с помощью Geolocation HTML5

Как узнать регион пользователя который зашёл на сайт?


Ответ

Что-то подобное можно использовать (определение местоположения по координатам):
HTML

Страна:

Край(обл.):

Город:

Адрес:

Широта:

Долгота:


JS
function displayError(error) { var errors = { 1: 'Нет прав доступа', 2: 'Местоположение невозможно определить', 3: 'Таймаут соединения' }; alert("Ошибка: " + errors[error.code]); }
function displayPosition(position) { var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=ru';
$.getJSON(GEOCODING).done(function(location) {
$('#address').html(location.results[0].formatted_address); $('#latitude').html(position.coords.latitude); $('#longitude').html(position.coords.longitude);
// в location.results[0] содержится больше всего информации об адресе for (var i = 0; i < location.results[0].address_components.length; i++) { switch(location.results[0].address_components[i].types[0]) { case 'locality': $('#city').html(location.results[0].address_components[i].long_name); break; case 'administrative_area_level_1': $('#state').html(location.results[0].address_components[i].long_name); break; case 'country': $('#country').html(location.results[0].address_components[i].long_name); break; } } }) }
if (navigator.geolocation) { var timeoutVal = 10 * 1000 * 1000; navigator.geolocation.getCurrentPosition( displayPosition, displayError, { enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 } ); } else { alert("Geolocation не поддерживается данным браузером"); }
Рабочий пример: https://jsfiddle.net/tty37u7m/6/ (сюда в код не удалось импортировать этот пример, geolocation не реагирует)

Восстановление файлов из .git [дубликат]

На данный вопрос уже ответили: Как отменить откат изменений (восстановить потерянный коммит)? 1 ответ По неопытности сделал git reset --hard HEAD~2 , когда было всего 2 коммита(не было ни одного pushа к тому времени, только файлы в локальной репе), не знал, что это целиком захватывает файлы:(, в результате получил пустую директорию с .git (600мб), можно ли восстановить файлы?!, если да, то как?Или как-нибудь вернуться на 1 коммит после? Сроки горят, очень нужно! Не доверяйте этой статье! https://habrahabr.ru/post/138590/


Ответ

да, скорее всего можно. Выполните команду git reflog - это лог Вашей локальной работы. Там Вы как раз увидите свои sha хеши коммитов. Теперь можно попробовать сделать git checkout - то есть где то так git checkout ab1cd3. Если Вам повезет, то сорцы будут восстановлены. А дальше от этого можно сделать новую ветку (git branch recovery) и работать как обычно.

RabbitMQ несколько очередей на одного потребителя

В мою систему отправляется больше количество сообщений из разных систем. Допустим, сообщения для автомобилей разных марок.
При каждой отправке новой марки автомобилей из какой-либо системы создается новая очередь (например, auto.kia, auto.lada и т.п.) в итоге в реббите может быть произвольное количество очередей.
Но, у меня есть один воркер (Consumer), который должен собирать и обрабатывать сообщения из всех этих очередей. Как реализовать множества очередей одним воркером?


Ответ

Звучит как классический случай topic exchange
В них требуется, чтобы routing_key в сообщениях отправителя (producer) состоял из набора слов, разделённых точками, ваши auto.lada и auto.kia как раз подходят.
Тогда binding_key принимающего (consumer), содержащий спецсимволы * и # играет роль шаблона вроде регулярного выражения:
* означает "одно любое слово" # означает "любое число (даже 0) любых слов".
...и ключи auto.lada и auto.kia оба подойдут под шаблон auto.* у принимающего.
Переменной при таком раскладе будет не очередь, а ключ сообщений (routing key для отправителя). Распределение происходит в рамках одной очереди. Много очередей для этой цели вам и не нужно. Подробнее в руководстве по AMQP

Что значит стоимость вычисления при хэшировании пароля?

В мане по php столкнулся с такой функцией хэширования password_hash() в эту функцию передается три аргумента: пароль, алгоритм шифрования, дополнительные опции
Дополнительные опции здесь передаются как ассоциативный массив...в одном примере мана написано так:
$options = [ 'cost' => 11, 'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM), ];
Понятно что salt - это соль и под значением понимается функция которая генерирует эту соль, но мне неясно одно, что такое cost, и какую роль оно играет при шифровании?


Ответ

Вот достаточно развернутый ответ на английском языке. А на Wiki есть описание алгоритма, где вы можете понять, в каком месте используется cost.
Если коротко, то cost влияет на количество операций при получении хэша, как степень числа 2. При cost = 11 у вас будет 2**11 повторений алгоритма для вычисления.

Почему во многих языках индексирование начинается с 0?

По-моему, это из электроники, разве нет? С чего вообще это пошло?


Ответ

В первую очередь потому, что с точки зрения реализации понятие "индекса" элемента в непрерывном агрегате напрямую связано с понятием "смещения" элемента от начала агрегата в памяти. Понятно, что смещение самого первого элемента агрегата равно нулю. Соответственно и индекс его разумно взять равным нулю.
Другими словами, как ни верти, но индекс первого элемента в агрегате все равно придется пересчитывать в значение 0 на машинном уровне. В такой ситуации реализация индексации с ненулевой базой будет всегда волей-неволей подразумевать неявное приведение ее к индексации с нулевой базой. В многих языках программирования просто не считают необходимым это делать. Зачем, действительно?

Текст в TextView не более 2х строк, а если больше, то три точки добавить. Как сделать?

Нужно отобразить текст в TextView, но не более 2х строк, а если больше, то добавить три точки в конце. Как это сделать?


Ответ

android:maxLines="2" android:ellipsize="end" android:singleLine="false"

Как удалить неиспользуемые стили из CSS?

Имеется HTML и CSS файл, в котором много неиспользуемых стилей CSS которые хотелось бы удалить в автоматическом режиме и оставить только те стили, которые используются. Как и чем это сделать?


Ответ

Используйте uncss
gulp-uncss,
npm uncss
А для сборки, нужно скачать и установить node.js, в проекте создать файлы: package.json, gulpfile.js.
Минимальное содержимое package.json: { }
В командной строке (лучше бы coneEmu консоль) выполнить установку gulp npm install -g gulp npm install --save-dev gulp
Установить gulp-uncss: npm install --save-dev gulp-uncss
Настроить проект в gulpfile.js (посмотреть в описании gulp-uncss + примеров в сети полно).
Минимальный gulpfile.js
var gulp = require('gulp'); var uncss = require('gulp-uncss');
gulp.task('default', function () { return gulp.src('site.css') // исходник .pipe(uncss({ html: ['index.html', 'posts/**/*.html'] })) .pipe(gulp.dest('./out')); // результат });
... Это если коротко.
P.S: Если нет времени, то тогда только руками удалять не нужные стили.

в чем проблема с отсутствием мьютексов в коде?

здравствуйте, начинаю очередной раз разбираться с многопоточностью... нашел простой пример для наглядности рассинхронизации доступа, но не понимаю некоторых вещей:
struct Counter { int value;
Counter() : value(0){}
void increment(){ ++value; } };
int main() { Counter counter;
std::vector threads; for(int i = 0; i < 5; ++i){ threads.push_back(std::thread([&counter](){ for(int i = 0; i < 100; ++i){ counter.increment(); } })); }
for(auto& thread : threads){ thread.join(); }
std::cout << counter.value << std::endl;
return 0; }
совершенно не могу понять почему вылетают разные значения... у нас ведь join() т.е. мы ждем когда каждый из пяти потоков выполнится один за другим(т.е. инкрементирует по 100 раз каждый), я понимаю если б detach() стоял, то была бы жесть... а так каждый поток из пяти один за другим ведь следом идут... почему значения отличные от 500 получаются. либо я чего-то не учитываю... разве не верно, что в первом потоке будет 100, и в последующих будут на 100 больше?


Ответ

У Вас не синхронизирован доступ к counter, поэтому, в силу data races, как Вам уже правильно указал VladD, у Вас в коде UB. Чтобы исправить код, Вам нужно синхронизировать доступ к counter внутри, или снаружи. Можно сделать так:
struct Counter { std::atomic_int value; ... };
Или так:
std::mutex guard;
std::vector threads; for(int i = 0; i < 5; ++i) { threads.push_back(std::thread([&counter, &guard]() { for(int i = 0; i < 100; ++i) { std::lock_guard lock{guard}; counter.increment(); } })); }
Или ещё массой других вариантов — главное, чтобы пропали гонки(data races)

Разница между global и $GLOBALS

В интернете видел что пишут разница лишь в написании, так ли это?
Снизу товарищ Saidolim написал один пример, хочу продолжить вопрос...
Есть такой код
/// Пример 1 $str = "Simple text"; $a = function() { global $str; $str = "edited"; }; $a(); echo $str."
"; /// edited
/// Пример 2 $str = "Simple text"; $a = function() { $GLOBALS["str"] = "edited"; }; $a(); echo $str."
"; /// edited
/// Пример 3 $str = "Simple text"; $temp = ""; $a = function() { $GLOBALS["temp"] = &$GLOBALS["str"]; }; $a(); echo "[".$str."] [".$temp."]
"; /// [Simple text] [Simple text]
/// Пример 4 $str = "Simple text"; $temp = ""; $a = function() { global $str, $temp; $temp = &$str; }; $a(); echo "[".$str."] [".$temp."]
"; /// [Simple text] []
Первый пример выводит как и ожидается измененное значение, второй пример то же самое...казалось бы отличия нет, идем дальше! В третьем примере в функции мы делаем жесткую ссылку для элементов суперглобального массива выводит как и ожидается одно и то же слово, и вот смотрим четвертый пример и ... я в ступоре он не линкует и выводит только переменнную $str, а переменную $temp оставляет пустой, почему?
P.S Написал тут ибо не хотел спамить вопросами по одному и тому же


Ответ

Инструкция global обращается к глобальному массиву $GLOBALS. И получает значение переменной $GLOBALS['var']. Отличие только в написании.
P.S. Совет при использовании глобальных переменных: держитесь от них подальше, используя их только тогда, когда без них не обойтись.
Злоупотребление глобальными переменными может довести человека анализирующего ваш код до белой горячки.

Синхронизация с использованием asynс/await

Есть такой код (взят у Шилдта и немного упрощен).
using System; using System.Threading; class ThreadTest { object lk = new object(); public void Tick() { lock (lk) { for (int x = 0; x < 12; x++) { Console.WriteLine("tick"); Thread.Sleep(200); Monitor.Pulse(lk); Monitor.Wait(lk); } Monitor.PulseAll(lk); } }
public void Tock() { lock (lk) { for (int x = 0; x < 12; x++) { Console.WriteLine("tock"); Thread.Sleep(200); Monitor.Pulse(lk); Monitor.Wait(lk); } Monitor.PulseAll(lk); } } } class demo { static void Main() { ThreadTest thrTest = new ThreadTest(); Thread t1 = new Thread(thrTest.Tick); t1.Start(); Thread t2 = new Thread(thrTest.Tock); t2.Start(); } }
Этот код в разных потоках запускает методы и синхронизируя их работу выводит на консоль Тик или Так. Но вот задумался, а как можно такой же функционал реализовать, но используя asynс/await ? И реально ли это ?


Ответ

Да, можно, хотя это немного сложнее.
Вот в этой статье расписана механика того, как сделать это самостоятельно. Но лучше не изобретать велосипед, а воспользоваться готовой библиотекой AsyncEx. С подключением этой библиотеки можно написать просто:
readonly AsyncLock mutex = new AsyncLock(); public async Task UseLockAsync() { using (await mutex.LockAsync()) { // тут вам принадлежит lock } }
(Оба автора — признанные специалисты в асинхронном программировании. Stephen Toub — один из разработчиков TPL в Microsoft, Stephen Cleary — автор хорошей книги Concurrency in C# Cookbook.)

По поводу конкретного кода с очерёдностью выполнения — такое можно сделать проще. Я использовал для синхронизации двух потоков AsyncBarrier из того же Nito.AsyncEx
class Program { static void Main(string[] args) { new Program().Run().Wait(); }
async Task Run() { pingBarrier = new AsyncBarrier(2); pongBarrier = new AsyncBarrier(2); var ping = Ping(); var pong = Pong(); await ping; await pong; }
AsyncBarrier pingBarrier, pongBarrier;
async Task Ping() { for (int i = 0; i < 12; i++) { await pingBarrier.SignalAndWaitAsync(); pingBarrier = new AsyncBarrier(2); Console.WriteLine($"ping #{i}, thread {Thread.CurrentThread.ManagedThreadId}"); await pongBarrier.SignalAndWaitAsync(); } }
async Task Pong() { for (int i = 0; i < 12; i++) { await pingBarrier.SignalAndWaitAsync(); await pongBarrier.SignalAndWaitAsync(); pongBarrier = new AsyncBarrier(2); Console.WriteLine($"pong #{i}, thread {Thread.CurrentThread.ManagedThreadId}"); } } }

Заметьте, что первоначальный пример Шилдта неправилен. Он использует Thread.Sleep для того, чтобы «гарантировать» наличие ожидающего потока, что является грубым просчётом. Из документации на Monitor.Pulse
The Monitor class does not maintain state indicating that the Pulse method has been called. Thus, if you call Pulse when no threads are waiting, the next thread that calls Wait blocks as if Pulse had never been called. If two threads are using Pulse and Wait to interact, this could result in a deadlock.
Впрочем, Шилдт знаменит неаккуратностью в своих книгах.

Уточнение: нет, пример Шилдта всё же правилен, Thread.Sleep в нём не играет решающей роли. Тем не менее, приведённая цитата из MSDN всё ещё в силе, и использование Wait/Pulse для синхронизации потоков опасно.

C#: в чем отличие Lazy от аналогичных реализаций?

Здесь показан пример отложенной инициализации свойства класса, выглядит это так:
private Lazy _someVariable =new Lazy(SomeClass.IOnlyWantToCallYouOnce); public string SomeVariable { get { return _someVariable.Value; } }
Возник вопрос: чем отличается вышеуказанная инициализация от например такой:
private string? _someVariable = null; public string SomeVariable { get { if(_someVariable == null) { // здесь могу ошибаться, но думаю, что принцип понятен _someVariable = new SomeClass().IOnlyWantToCallYouOnce(); } return _someVariable; } }


Ответ

У Lazy есть потокобезопасная версия, при реализации же ленивости вручную надо городить DCL и не забыть про volatile Второй вариант использует null как маркер отсутствия значения. Если вдруг функция IOnlyWantToCallYouOnce() вернет null - она будет вызвана еще раз. У Lazy же null - такое же допустимое значение, как и любое другое, потому что маркер наличия значения хранится отдельно от самого значения. Lazy сохраняет не только результат нормального вычисления - но и исключение в случае ошибки, поэтому функция IOnlyWantToCallYouOnce будет вызвана только 1 раз чего бы не случилось. Решение же номер два в случае исключения при вызове ничего не сохранит и при повторном обращении попытается получить его еще раз. Иногда это полезно, иногда - вредно.

Объясните особенности перегрузки операторов в С++

class Integer { private: int value; public: Integer(int i): value(i) {} const Integer operator+(const Integer& rv) const { return (value + rv.value); } };
Возьмём за основу этот код. И вот вопросы: 1. Почему возвращаемое значение не является ссылкой? Разве не рациональнее было бы написать const Integer&... 2. Что означает, что возвращаемое значение является const? Что в данном случае я не смогу поменять с возвращаемым объектом?


Ответ

Почему возвращаемое значение не является ссылкой? Разве не рациональнее было бы написать const Integer&...
Встречный вопрос: а ссылку на что вы будете возвращать? Результатом операции сложения левого и правого операнда является новый объект. Его вы и возвращаете. В данном месте просто семантика говорит возвращать объект, а не ссылку на него. А дальше... Скорее всего сработает оптимизация VRO и лишних конструкторов/копирований вызываться не будет.
Что означает, что возвращаемое значение является const? Что в данном случае я не смогу поменять с возвращаемым объектом?
Нет. Нужно спрашивать дизайнера класса. Скорее всего сделано, дабы нельзя было у временного объекта вызвать неконтантные методы, например в таком случае:
Integer a{1}; Integer b{2}; (a + b).someMethod(); // или (a + b)++; // при наличии реализации operator++ в постфиксной форме
Если метод someMethod() будет без квалификатора const, то, с точки зрения дизайна, он может изменить состояние класса и с данной реализацией будет ошибка компиляции. Поиграться можно тут: http://ideone.com/6ILKdJ
Просто присваивание создаст "копию" и константность на вас никак не повлияет: вы уже будете работать с другим объектом, т.е. в код ниже абсолютно легитимен:
Integer a{1}; Integer b{2}; Integer c = a + b c++; // при наличии реализации operator++ в постфиксной форме
Хотя возможно, что это просто результат копипасты.

Как в WordPress зарегистрировать и добавить выпадающее при наведении меню?

Есть сайт на WordPress, где в тему хочу добавить bootstrap меню с выпадающим списком при наведении. Регистрирую меню стандартным способом:
register_nav_menus(array( 'top' => 'Верхнее меню' ));
wp_nav_menu( array( 'container' => 'div', 'container_class' => 'collapse navbar-collapse navbar-ex1-collapse', 'menu_class'=>'nav navbar-nav navbar-right', 'theme_location'=>'top' ) ); ?>
Затем хочу перенести в него функционал этого меню, но есть проблемы с добавлением в ссылку классов class="dropdown-toggle" атрибутов data-toggle="dropdown" и во внутренний список ul класса dropdown-menu. Как это можно сделать? фидл
.dropdown:hover > .dropdown-menu { display: block; }



Ответ

Нужно использовать класс Walker, следующий код при добавлении в function.php, добавляет нужные классы к пунктам меню и ссылкам внутри него, при этом стандартные классы меню wordpress не выводятся.
class mainMenuWalker extends Walker_Nav_Menu { function start_el(&$output, $item, $depth, $args) { // назначаем классы li-элементу и выводим его $class_names = ' class="main-menu_item"'; $output.= '';
// назначаем атрибуты a-элементу $attributes.= !empty( $item->url ) ? ' href="' .esc_attr($item->url). '" class="main-menu_link" ' : ''; $item_output = $args->before;
// проверяем, на какой странице мы находимся $current_url = (is_ssl()?'https://':'http://').$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; $item_url = esc_attr( $item->url ); $item_output.= ''.$item->title.'';
// заканчиваем вывод элемента $item_output.= $args->after; $output.= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); } }
И в шаблоне где выводиться меню, выводим его следующим образом:
'header_menu', 'container' => 'nav', 'container_class' => 'main-menu', 'menu_class' => 'main-menu_list', 'menu_id' => 'menu-header', 'walker' => $main_menu )); ?>
В этом варианте конечно классы добавляются напрямую, без использования массива classes и у вложенного меню у тега ul генерируется дефолтный класс sub-menu Если же необходим более тонкий контроль, то еще немного расширим класс Walker:
class mainMenuWalker extends Walker_Nav_Menu { //для начала зададим класс для вложенного пункта меню тегу ul //функция start_lvl формирует превую строчку в шаблоне вывода списка, это нам и нужно. function start_lvl( &$output, $depth = 0, $args = array() ) { $indent = str_repeat("\t", $depth); $output .= "
$indent


    ";// указываем нужный нам класс, теперь все вложенные теги ul будут иметь указанный класс. } // если необходимо обозначить тег li, что он является родительским элементом вложенного списка модифицируем немного функцию display_element. function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) { //получим id элемента пункта меню $parent_elem = $this->db_fields['id']; // проверим есть ли в нем вложенный список if ( !empty( $children_elements[ $element->$parent_elem ] ) ) { // запишем в массив classes необходимый нам класс и присвоим элементу списка $element->classes['parent_class'] = 'parent-item'; } Walker_Nav_Menu::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); } //Ну а здесь уже приведем в нужный нам вид классы li элемента function start_el(&$output, $item, $depth, $args) { // назначаем классы li-элементу и выводим его //для этого добавим наш класс в массив classes $item->classes['my_class'] = 'main-menu_item'; // и напрямую укажем какие классы из массива мы хотим использовать. $class_names = ' class="' .esc_attr( $item->classes['my_class'] .' '. $item->classes['parent_class'] ). '"'; $output.= '
  • ';
    // назначаем атрибуты a-элементу $attributes.= !empty( $item->url ) ? ' href="' .esc_attr($item->url). '" class="main-menu_link" ' : ''; $item_output = $args->before;
    // проверяем, на какой странице мы находимся $current_url = (is_ssl()?'https://':'http://').$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; $item_url = esc_attr( $item->url ); $item_output.= ''.$item->title.'';
    // заканчиваем вывод элемента $item_output.= $args->after; $output.= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); } }
    PS Eсли хотим использовать все классы и дефолтные, указываем просто массив $item->classes
    тогда строка будет иметь вид:
    $class_names = join( ' ', $item->classes ); $class_names = ' class="' .esc_attr( $class_names ). '"'; $output.= '

В каких случаях использовать указатель на базовый класс, а в каких на наследник?

Не могли бы вы прокомментировать этот момент:
Используя виртуальные функции для обеспечения полиморфизма необходимо использовать указатель именно на базовый класс.
В каких случаях необходимо использовать указатель на класс наследник, а в каких на базовый класс?
Просто недавно наткнулся на такой пример, он корректно реализован?
#include using namespace std;
class Base { //Базовый класс public: int base_data; Base(int base_data);//Конструктор класса virtual void Virtual_method(); // Виртуальный метод void Nonvirtual_method(); // Не виртуальный метод virtual~Base(); //Виртуальный деструктор };
Base::Base(int base_data){ this->base_data = base_data; cout << "Конструктор базового" << endl; }
void Base::Virtual_method() { cout << "Виртуальный метод базового класса
"; }
void Base::Nonvirtual_method() { cout << "Не виртуальный метод базового класса
"; }
Base::~Base(){ cout << "Деструктор базового класса
"; }
class Derived : public Base {//Класс наследник public: double derived_data; Derived(double derived_data, int base_data); void Virtual_method(); // Переопределённый виртуальный метод базового класса void Nonvirtual_method(); //Не виртуальна функция ~Derived(); };
Derived::Derived(double derived_data, int base_data):Base(base_data){ this->derived_data = derived_data; cout << "Конструктор наследника" << endl; }
void Derived::Virtual_method() { cout << "Переопределённый виртуальный метод класса наследника
"; }
void Derived::Nonvirtual_method() { cout << "Не виртуальный метод класса наследника
"; }
Derived::~Derived(){ cout << "Деструтор класса наследника
"; }
int main() { setlocale(LC_ALL, "RUS"); Derived derived(2.0, 1);//Объявили объект класса наследника
Derived *pDerived = &derived;//Объявили указатель на класс наследник, присвоив ему ссылку на объект класса наследника Base *pBase = &derived;//Объявили указатель на базовый класс, присвоив ему ссылку на объект класса наследника
pBase->Virtual_method(); // Вызов виртуального метода pBase->Nonvirtual_method(); // Вызов не виртуального метода pDerived->Virtual_method(); // Вызов виртуального метода pDerived->Nonvirtual_method(); // Вызов не виртуального метода cout << "base_data = " << derived.base_data << "
derived_data = " << derived.derived_data << "
"; return 0; }


Ответ

Обычно, когда говорят о полиморфизме в программировании, то пытаются дать определение этого слова в терминах языков программирования.
Однако на мой взгляд более удачное определение полиморфизма дается в биологии. Только слово организм в этом определении следует заменить словом объект в терминах программирования.:)
Полиморфи́зм в биологии (от др.-греч. πολύμορφος — многообразный) — способность некоторых организмов существовать в состояниях с различной внутренней структурой или в разных внешних формах
В вашей демонстрационной программе определяется указатель типа Base *, то есть статический тип объектов, адресуемых этим указателем является тип Base
Base *pBase;
Когда такому указателю присваивается адрес объекта производного класса, то объект, к которому происходит обращение через этот указатель, рассматривается как объект типа Base. Фактически, вся информация о том, что этот объект на самом деле является производного класса, а не базового, теряется. так как статический тип указателя Base *
Однако благодаря наличию такого средства, как виртуальные функции, позволяет получать многообразие поведения адресуемого указателем объекта в зависимости от того, какой тип на самом деле имеет адресуемый объект. То есть через виртуальные функции имеется возможность различать реальный тип адресуемых объектов и обращаться к их уникальным свойствам. И это демонстрируется ваша программа на примере данных предложения
Base *pBase = &derived;//Объявили указатель на базовый класс, присвоив ему ссылку на объект класса наследника
pBase->Virtual_method(); // Вызов виртуального метода pBase->Nonvirtual_method(); // Вызов не виртуального метода
Как видно указатель типа Base * на самом деле адресует объект производного класса. Но если вызывать не виртуальный метод
pBase->Nonvirtual_method(); // Вызов не виртуального метода
то вся информация о производном классе недоступна, так как компилятор вызывает функции в соответствии со статическим типом объекта, адресуемого указателем, то есть в соответствии с типом Base. Компилятор при поиске имени функции, которую следует вызвать смотрит определение базового класса. Он ничего не знает о производных классах.
Ежели вы вызываете виртуальную функцию
pBase->Virtual_method(); // Вызов виртуального метода
то компилятор также при поиске имени вызываемой функции смотрит определение базового класса. Однако тут происходит некоторый фокус. Производный класс подменил определение виртуальной функции в базовом классе своим определением этой функции. Технически это делается следующим образом. Если класс объявляет виртуальную функцию, то он создает таблицу указателей на виртуальные функции, объявленные в своем определении. Производные же классы, которые переопределяют виртуальные функции подставляют в эту таблицу базового класса адреса своих определений функций. Поэтому динамически во время выполнения программы вызывается та функция, чей адрес находится в таблице адресов виртуальных функций.
Что касается вашего вопроса
В каких случаях необходимо использовать указатель на класс наследник, а в каких на базовый класс?
То когда вы объявляете указатель на класс наследник, то вы теряете полиморфизм, так как вы можете работать только с объектами класса наследника (я предполагаю, что наследник в свою очередь не наследуется другими классами). А когда вы хотите достичь поведение, соответствующее полиморфизму, то
1) базовый класс должен содержать виртуальные функции т 2) следует объявить указатель или ссылку, имеющую статический тип указателя или ссылки на объекты базового класса, а инициализировать их объектами производных классов.
И тогда вы получите
способность некоторых объектов (организмов) существовать в состояниях с различной внутренней структурой или в разных внешних формах
Примечание. Если при вызове виртуальной функции вы указываете ее квалифицированное имя, то "виртуальность" исчезает. Вызывается функция класса, определенная в этом же классе.
Рассмотрите пример
#include
struct Base { virtual ~Base() { } virtual void virtual_function() const { std::cout << "Base::virtual_function() is called" << std::endl; } };
struct Derived : Base { void virtual_function() const override { std::cout << "Derived::virtual_function() is called" << std::endl; } };
int main() { Derived d;
Base &rBase = d;;
rBase.virtual_function(); rBase.Base::virtual_function();
return 0; }
Ее вывод на консоль будет следующим
Derived::virtual_function() is called Base::virtual_function() is called
В первом случае вступает в игру полиморфизм. Вызывается переопределенная виртуальная функция производного класса Derived, хотя базовый тип ссылки - это класс Base
Во втором случае, когда используется квалифицированное имя, "виртуальность" фукнции пропадает, и вызывается реализация функции базового класса Base

Как получить короткое имя типа?

Вызывая код
typeof(int).Name
я получаю "Int32"
А как мне получить короткие имена типов? То есть вместо Int32 - int, Int64 - long и тд. Ручной маппинг не предлагать, это я и сам могу. Просто подумал, может есть более красивое решение.


Ответ

Можно воспользоваться Microsoft.CSharp.CSharpCodeProvider.GetTypeOutput
var compiler = new CSharpCodeProvider();
var type = new CodeTypeReference(typeof(int));
Console.WriteLine(typeof(int).Name); Console.WriteLine(compiler.GetTypeOutput(type));
Output:
Int32 int

Как скопировать файлы из одной папки в другую?

Добрый день, завис на методе copy не могу понять как им воспользоваться ?
public static void main(String[] args) throws InterruptedException, IOException { ArrayList selectFiles = new ArrayList<>(); File folder = new File("путь"); File[] listOfFiles = folder.listFiles();
for (File f : listOfFiles) { selectFiles.add(f + ""); }
File source = new File(" " + selectFiles);// ПОЛУЧАЮ СПИСОК ФАЙЛОВ ПРИСВАИВАЮ ПЕРЕМЕННУЮ С ФАЙЛАМИ File dest = new File("путь");// ПРОПИСЫВАЮ ПУТЬ КУДА КОПИРОВАТЬ copy(source, dest); }
public static void copy(File source, File dest) throws IOException { Files.copy(source.toPath(), dest.toPath()); }
Но так не работает выдаёт ошибку
Exception in thread "main" java.nio.file.InvalidPathException: Illegal char <:> at index 3: с перечеслением всех файлов в папке


Ответ

У вас неправильно формируется имя файла для source
Код должен выглядеть примерно так:
private static void copyDir(String sourceDirName, String targetSourceDir) throws IOException { File folder = new File(sourceDirName);
File[] listOfFiles = folder.listFiles();
Path destDir = Paths.get(targetSourceDir); if (listOfFiles != null) for (File file : listOfFiles) Files.copy(file.toPath(), destDir.resolve(file.getName()), StandardCopyOption.REPLACE_EXISTING);
}

Настройка отношения one to zero-or-one совместно с one-to-many

Есть работающее приложение/вебсайт, в котором можно в паспорт автомобиля подгружать картинки, одна из картинок считается "заглавной". Первая загруженная картинка становится заглавной, впоследствии можно поменять.
Соответственно, были следующие классы:
public class Car { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; }
[Required] public string Title { get; set; } }
и
public class CarImage { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; }
[Required] public int CarID { get; set; }
[ForeignKey("CarID")] public virtual Car Car { get; set; }
public string FileName { get; set; }
public bool IsPrimaryImage { get; set; } }
И как-то знакомые предложили мне попробовать отрефакторить это следующим образом: не помечать заглавную картинку как IsPrimaryImage = true, а вынести в свойство PrimaryImage:
public class CarImage { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; }
[Required] public int CarID { get; set; }
[ForeignKey("CarID")] public virtual Car Car { get; set; }
public string FileName { get; set; } }
и
public class Car { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; }
[Required] public string Title { get; set; }
public int? PrimaryImageID { get; set; }
public virtual CarImage PrimaryImage { get; set; } }
Однако чем больше я вникаю в эту задачу - тем больше понимаю, что она не такая простая как мне показалось на первый взгляд.
Сначала я думал обойтись только data anntotation (не очень люблю fluent API, когда определения где-то отдельно от таблиц), есть мой топик на en-so, где я пытался расставить атрибуты.
Однако проблемы начались когда я начал пытаться сохраниться в базу:
using (var db = new DataContext()) { var car = db.Car.First(x => x.ID == CarID);
var image = new CarImage { CarID = car.ID, //Car = car, IsDeleted = false, };
db.CarImages.Add(image);
db.SaveChanges();
if (isFirstImage) { car.PrimaryImage = image; car.PrimaryImageID = image.ID; }
db.SaveChanges(); }
(Ошибок было много разных, могу привести, но как мне кажется, что там нет ничего полезного для дальнейшего обсуждения)
После чего я решил оставить эти попытки и использовать fluent API:
modelBuilder.Entity() .HasRequired(x => x.Car) .WithOptional(x => x.PrimaryImage) .Map(x => x.MapKey("PrimaryImageID"));
И... тоже как ни странно стал получать те или иные ошибки. Тоже не привожу, т.к. в этот момент я понял, что нужно разбираться основательно и сначала.
Итак, для начала разберёмся с отношениями в базе
У одного автомобиля может быть несколько изображений -- это очевидно, связь one-to-many.
Но, с другой стороны, у каждого автомобиля может быть одна заглавная картинка -- это очевидно связь one to zero-or-one.
Как правильно прописать эти связки в моих классах?
В контроле у меня собственно всего лишь две вьюхи:
нужно вывести список машин с заглавными картинками (или картинкой-заглушкой, если картинок ещё нет); нужно вывести карточку машины со списком параметров и всеми картинками, которые относятся к этой машине.
И, как раз в первой будут намного лучше план запроса к БД, если сделать рефакторинг.
Пробовал такой вариант решения:
public class Car { [Key] public int ID { get; set; }
[Required] public string Title { get; set; }
public int? PrimaryImageID { get; set; }
[ForeignKey("PrimaryImageID")] public virtual CarImage PrimaryImage { get; set; }
public virtual ICollection AllImages { get; set; } }
и
public class CarImage { [Key] [ForeignKey("Car")] public int ID { get; set; }
[Required] public int CarID { get; set; }
[ForeignKey("CarID")] public virtual Car Car { get; set; }
public string FileName { get; set; } }
я описывал в чате, как я к нему шёл, там же можно найти проблемы, с которыми я столкнулся и пока не смог решить.


Ответ

Вы слишком все усложнили. Атрибут
[ForeignKey("Car")] public int ID { get; set; }
Т.е. ок, вы скопировали его из статьи про one-to-one or zero - но нужно понимать, за счет чего достигается эта связь.
По сути, вы просто говорите "ID картинки должен быть равен ID существующей машины". Достаточно очевидно, что при этом у машины может быть не больше одной картинки. Вы физически не можете записать в базу картинку с ID = 2, если в базе нет машины с ID = 2. Никак. Вы явно обозначили это в своей модели. В вашей модели в базе не может быть ровно одна машина и две картинки - то ID у картинок должны быть равны, и вы просто не сможете их различить.
И тут же вы пытаетесь заявить "но у машины (как-то!) может быть несколько картинок!" - что делает вашу модель противоречивой. И EF умирает.
Не усложняйте. Просто уберите лишнее - лишние атрибуты, лишние вызовы SaveChanges, возможность достать машину из CarImage (можно оставить, но скорее всего она не нужна) и оставить работу через сущности - все заработает именно так, как вы хотите. Вот минимальный рабочий пример:
public class Car { public int ID { get; set; }
public virtual CarImage PrimaryImage { get; set; }
public virtual ICollection AllImages { get; set; } }
public class CarImage { public int ID { get; set; } } public class Model1 : DbContext { public Model1() : base("name=Model1") { }
public DbSet Cars { get; set; } }
using (var db = new Model1()) { var car = db.Cars.First(x => x.ID == 1); bool isFirstImage = !car.AllImages.Any();
var image = new CarImage();
car.AllImages.Add(image);
if (isFirstImage) { car.PrimaryImage = image; }
db.SaveChanges(); }
По желанию можно вернут на место все PrimaryImageId, CarID, Car DbSet - все будет работать точно так же (т.е. вы этим сможете явно сделать это позволит вам сделать связь CarImage -> Car обязательной, но сейчас она все равно практически обязательна - т.к. у CarImage нет Car - вы не можете его занулить :) )

Производитель JVM

Как узнать производителя JVM? Как я понимаю, существует несколько производителей JVM: Oracle (Oracle Hotspot), сообщество свободного программного обеспечения (OpenJDK), IBM (IBM J9), Azul Systems (Zing) и другие. Как (по пакету jdk) можно узнать, чья версия JVM используется?


Ответ

System.getProperty("java.vendor"); System.getProperty("java.vm.name");

Является ли данный код рекурсивным?

Есть задание
Найти методом деления отрезка пополам минимум функции f(x) = 7sin(2x) на отрезке [2, 6] с заданной точностью ε (например, 0.01). Разумеется, его нужно написать
#include #include #include using namespace std;
const double eps = 0.01; double a, b, t, x, y, t1, s;
double func(double a, double b) { s = (a + b) / 2; y = (7 * sin(2)*s); return y; }
int main() { a = 2; b = 6; while (abs(b - a) < eps); { t = (a + b) / 2.0; y = 7 * sin(2)*(t - eps); x = 7 * sin(2)*(t + eps); if (y <= x) { a = t; t1 = func(a, b); } else { b = t; t1 = func(a, b); } } cout << "Otvet: " << t1; return 0; }
Проблема в том, что преподаватель говорит, что задача решена не рекурсивно. Я утверждаю что решение рекурсивно, так как функция double func принимает значение из функции int main. Прав ли я?


Ответ

Верно будет так (примерны код):
rec(double a, double b){ (здесь все ваши действия с синусами) if (abs(b - a) < eps) // проверяем новые значения - надо еще раз пересчитать? rec(a, b) // вызываем саму себя с новыми значениями else return ... // иначе - возвращаем ответ }
И в мейне вызываем эту функцию,не забыв передать в нее начальные a и b

что можно сделать для обеспечения потокобезопасности?

Здравствуйте. Был на собеседовании... В итоге озадачили следующим вопросом (примерно).
Вот, допустим, есть сишная либа в исходниках... Там куча глобальных переменных... Но она писалась не под многопоточные приложения... Что можно сделать, чтобы обеспечить более-менее адекватное использование этой либы в многопоточных приложениях, притом, что существенно менять исходники нельзя(да и слишком непосильная задача будет)? В общем, что-то нужно сделать с глобальными переменными, но что?


Ответ

Один [наивный] подход - разнести вызовы этих функций из разных потоков по времени, т.е. заоболочить каждый вызов в критическую секцию. Однако имейте в виду, что такой подход не будет применим, если рассматриваемые глобальные переменные используются для сохранения состояния между вызовами этих функций. Если учесть, что в 9 случаях из 10 глобальные переменные заводятся именно для таких целей, применимость такого подхода выглядит сомнительной.
Например (не ходя далеко за примером), сериализация вызовов стандартной функции strtok из разных потоков через критическую секцию никак не сделает ее работоспособной в многопоточной среде, ибо она использует глобальную переменную для сохранения состояния между вызовами.
(Интересно было бы поспорить на тему того, можно ли таким образом адаптировать к многопоточности функцию rand(), которая, как известно, тоже обладает сохраняемым между вызовами состоянием :) ) Второй подход - разнести конфликты между этими функциями в пространстве (в памяти). А именно: объявить все глобальные переменные, как thread local, используя С11 спецификатор _Thread_local. Это не потребует какого-то существенного изменения исходников. (Многие пре-С11 компиляторы С давно предоставляют аналогичную функциональность в качестве расширения - тот же __thread в GCC или __declspec(thread) в MSVC.)
Этот подход несравнимо более надежен, но опять же, вопрос тут в том, устроит ли вас ситуация, когда в каждом потоке функции библиотеки будут вести себя "изолированным" образом по отношению к глобальным данным, т.е. устроят ли вас, к примеру, изолированные счетчики открытых файлов, изолированные глобальные флаги состояния и т.п. Так что работоспособность такого подхода тоже не является очевидной.

Вызов методов класса через указатель на функцию

Хочу реализовать возможность передавать в качестве аргумента функции указатель на метод разных классов.
class A1 { public: void show() { std::cout << "A1" << std::endl; } };
class B1 { public: void show() { std::cout << "B1" << std::endl; } };
void callf(void (*fp)()) { fp(); }
int main() { callf(&A1::show); callf(&B1::show);
return 0; }


Ответ

В вашем варианте забыта мелочь - то, что нестатическая функция-член требует наличия объекта, для которого вызывается. Так что просто так вызвать не получится, нужен объект.
Или статическая функция.
Вот так - запросто:
class A1 { public: static void show() { std::cout << "A1" << std::endl; } };
class B1 { public: static void show() { std::cout << "B1" << std::endl; } };
void callf(void (*fp)()) { fp(); }
int main() { callf(&A1::show); callf(&B1::show);
return 0; }
Если все же не статические - то, например, вот:
class A1 { public: void show() { std::cout << "A1" << std::endl; } };
class B1 { public: void show() { std::cout << "B1" << std::endl; } };
template void callf(T& t, void (T::*f)()) { (t.*f)(); }
int main() { A1 a; B1 b; callf(a,&A1::show); callf(b,&B1::show);
return 0; }

Почему объект не наследует свойство своего прототипа?

var object1 = { property: "property1" }; object1.__proto__.property = "property2"; console.log(object1.property); //property1
Почему object1 не наследует свойство своего прототипа?


Ответ

Ещё как наследует:
var object1 = { property: "property1" }; object1.__proto__.property = "property2"; console.log(object1.property); //property1 delete object1.property; console.log(object1.property); //property2
Так и работает прототипное наследование - если свойства нет в объекте, оно ищется в свойствах прототипа, и так далее, пока не найдём или не кончится цепочка прототипов.

StackOverflowException при использовании get/set

При обращении к полю для получения значения, для которого заданы get и set происходит многократное обращение к этому полю, в результате чего генерируется StackOverflowException. Если же сделать поле доступным, т.е. public, проблема исчезает.
class Sphere : Figure { public int radius { get { return radius; } private set { radius = value; } }
//неважный код
public Sphere(int r, double d) : base(d) { this.radius = r; } }


Ответ

У вас код:
int radius { get { return radius; } private set { radius = value; } }
при присвоении вы вызываете замкнутый цыкл, с которого невозможно выйти.(включи дебаг и понажимай F11 что бы увидеть что именно комп делает)
нужно писать
private int _radius; public int Radius { get { return _radius; } private set { _radius = value; } }
и все будет в порядке.
Как другой вариант, достаточно написать:
public int radius { get; private set;}

обнуление массива без memset

здравствуйте, не могу понять следующий выхлоп:
ex::ex(): movq $0, (%rdi) movq $0, 992(%rdi) movq %rdi, %rcx leaq 8(%rdi), %rdi xorl %eax, %eax andq $-8, %rdi subq %rdi, %rcx addl $1000, %ecx shrl $3, %ecx rep stosq ret
для кода:
class ex { public: ex() :a{0} {} char a[1000]; };
int main() { ex a; }
читал, что rep stosq делает примерно то же, что и цикл, заполняя что-то пока ecx > 0, вот только не могу толком понять что. в подобных вопросах говорят, что вроде edi заполняется значениями из eax... однако полного понимания как достигается обнуление массива в 1000 элементов нету... разъясните по инструкциям что там и зачем, сдвиг на 3 или вот это, например, зачем:
movq $0, (%rdi) movq $0, 992(%rdi)
обновление: в общем, предыдущий выхлоп был с -fno-inline, без него генерится вот это:
subq $1016, %rsp movl $125, %ecx xorl %eax, %eax movq %rsp, %rdi rep stosq
вопрос тот же: что за треш с rep stosq?


Ответ

Сдвиг на 3 нужен потому, что компилятор желает использовать инструкцию rep stosq, которая заполняет память не побайтно, а по 8-байтным словам. Поэтому количество итераций, которое надо сделать инструкции rep stosq равно размеру буфера, деленному на 8. Это и есть сдвиг вправо на 3.
То есть при подходе "в лоб" надо просто сделать 125 итераций rep stosq Однако для того, чтобы rep stosq работала эффективнее, необходимо, чтобы ее целевой адрес был выровнен на границу 8 байт. Ваш буфер a не гарантированно выровнен на границу 8 байт. Поэтому компилятор делает следующее: первое и последнее 8-байтное слово вашего буфера обнуляются индивидуально. Именно это делают инструкции
movq $0, (%rdi) movq $0, 992(%rdi)
А далее компилятор вычисляет выровненный на границу 8 байт адрес, с которого надо начать обнуление оставшейся "серединки" вашего буфера
leaq 8(%rdi), %rdi andq $-8, %rdi
а также вычисляет, сколько надо сделать итераций rep stosq, чтобы обнулить эту "серединку". Для вычисления количества итераций мы вычитаем из ecx (который в этот момент содержит точное начало буфера), значение выровненного начала
subq %rdi, %rcx
Если произошло фактическое выравнивание, то значение rcx станет отрицательным (более того, даже при выровненном буфере rdi здесь содержит адрес второго слова, т.е. значение rcx в любом случае будет отрицательным). Затем
addl $1000, %ecx shrl $3, %ecx
вычислит требуемое количество итераций, которое в общем случае получится меньше, чем 125 (т.е. 124).

Как правильно верстать макет, когда ширина экрана меньше ширины макета в пикселях?

Ширина макета 1920px. Ширина монитора 1600px. Вопрос: как правильно верстать такой макет и соблюсти все размеры и отступы?


Ответ

1 - Уточните у заказчика, что он в курсе, что дизайнер сделал такой широкий макет. Предупредите, что без адаптивизации хорошо будет смотреться только на больших мониторах. Порой заказчики могут проглядеть ширину в макете дизайнера, не обратить внимания.
2 - Можете воспользоваться в дев тулс в хроме toggle device toolbar ctrl+shift+m. Там, в режиме reponsive можно вручную задать экрану ширину больше, чем монитор, при этом автоматически подберется зум. Работать будет даже пиксель перфект, однако будет достаточно мелко.
3 - Можете задать изначально для body в стилях фиксированную минимальную ширину равную 1920px. Появится горизонтальный скролл, и вы будете верстать пиксель в пиксель, не очень удобно конечно скроллить, однако не будет мелко, как в предыдущем варианте.

Причем, обратите внимание, что обратный зум не покажет вам реальной картины, и результат верстки может отличаться от настоящих больших экранов.
Обратный зум - это когда нажимаете ctrl+- в хроме например, т.е 90%, 75% и.т.д.

Способ хранения координат фишек

Пишу бота, который будет играть в простейшую игру. В начале каждого хода из файла считывается игровое поле, которое представляет собой матрицу 8х8. В игре 4 игрока, их фишки, соответственно, обозначены цифрами 1, 2, 3, 4 и расставлены на игровом поле. Нужно найти все фишки каждого игрока и каким-то образом хранить местоположение (координаты) каждой фишки. Как можно это сделать? Пробовал запоминать координаты в обычный массив и в vector, но это не совсем удобно.


Ответ

Есть два варианта хранения - хранение состояния игры (доски), а на ней фишек (например, массив
int board[8][8];
в котором пустые поля обозначены нулями, а непустые - номером стоящей там фишки.
Но исходя из "Необходимо, чтобы можно было максимально просто получить доступ к координатам выбранной фишки", вам нужен второй вариант - а именно, массив фишек с их координатами (x,y), которые можно реализовать как стандартный pair, а можно с помощью своей структуры типа
struct Point { int x,y; };
Но, как я понимаю, вам нужно и то, и другое - чтобы, зная фишку, сразу получить возможные ходы - например, пустая ли какая-то клетка?
Я бы просто делал класс типа Game, который бы хранил и доску, и четыре фишки, и при каждом ходе обновлял как координаты фишки, так и состояние доски. Интерфейс такого класса содержал бы функции для - возврата координат фишки номер N - возврата номера фишки на поле (x,y) (0, если пусто) - перемещения фишки N на новое поле.
Как бы вы ни старались, сделать этот класс медленным - с 64 полями - у вас не получится. Какое нужно внутреннее представление - смотрите сами, что вам привычнее.

Как связать radiobutton с select?

Как сделать так, чтоб при выборе в radio какого-то значение, то select переключался на это же значение?

1 2 3 4 5


Ответ

Вариант без jQuery с использованием индексов вместо value
var select = document.querySelector('select'); var inputs = document.querySelectorAll('input[name="select"]'); for (const i in inputs) { if (inputs.hasOwnProperty(i)) { inputs[i].addEventListener('change', function () { select.selectedIndex = i; }); } }
1 2 3 4 5
JSFiddle

C# Почему async/await может тормозить

C# async/await
public partial class MainWindow : Window { private static object sync = new object();
public MainWindow() { InitializeComponent(); }
private void btnStart_Click(object sender, RoutedEventArgs e) { Random rnd = new Random();
for (int i = 0; i <= 100; ++i) { KeyValuePair pr = new KeyValuePair(i.ToString(), rnd.Next(1251000, 1259999).ToString()); ProcessingTransactionAsync(pr); } }
private async void ProcessingTransactionAsync(KeyValuePair trn) { this.WriteLog($"{trn.Key}_{trn.Value}", $"----> 1");
TestResult trnRes = await Task.Run((Func)(() => { this.WriteLog($"{trn.Key}_{trn.Value}", $"----> 2"); return this.ProcessingTransaction(trn); })); }
private TestResult ProcessingTransaction(KeyValuePair trn) { this.WriteLog($"{trn.Key}_{trn.Value}", $"----> 3");
//Здесь ещё функции, функции, функции Thread.Sleep(1000);
TestResult value = new TestResult(); this.WriteLog($"{trn.Key}_{trn.Value}", $"----> 4"); return value; }
#region Additional
private void WriteLog(string nameLogFile, string message) { try { string pathToLog = "Log";
if (!Directory.Exists(pathToLog)) Directory.CreateDirectory(pathToLog);
string filename = Path.Combine(pathToLog, string.Format("{0}.log", nameLogFile)); string fullText = string.Format("[{0:dd.MM.yyy HH:mm:ss.fff}] {1}
", DateTime.Now, message); lock (sync) File.AppendAllText(filename, fullText, Encoding.GetEncoding("Windows-1251")); } catch { // Перехватываем все и ничего не делаем } }
#endregion }
На первой итерации в лог пишется сл.:
[21.06.2017 16:53:49.998] ----> 1 [21.06.2017 16:53:50.022] ----> 2
При 100 итерации
[21.06.2017 16:56:44.937] ----> 1 [21.06.2017 16:56:52.672] ----> 2
Что программа может делать так долго(около 8 секунд) между шагами "----> 1" и "----> 2" на 100 итерации? Можно ли это как-то исправить?


Ответ

Вы запускаете в цикле одновременно 100 тасков (ProcessingTransactionAsync): вы не дожидаетесь их окончания. Каждый из них запускает внутренний таск через Task.Run на пуле потоков.
Пул потоков работает так: если есть свободный поток, то задание выполняется на нём. Если нет, система пытается создать новые потоки до MaxThreads. Если потоков и так слишком много, система думает, что вы просто создаёте задания, не дожидаясь результата, и не создаёт новых потоков, а просто ждёт, пока какой-то из рабочих потоков не освободится, и лишь тогда отдаёт ему задание.
Думаю, у вас случилось именно это.

Как в регулярном выражении написать “или”?

Имеем строку url = 'http://site.loc/?a=1&search=abcdf'; и регулярное выражение re = /\&search\=.*?(?=\&)/g;
Только оно срабатывает, если находит за искомым словом символ & Если же его нет, то выражение не срабатывает.
Как мне исправить регулярное выражение, что бы оно выполнялось или до & или до конца строки $?


Ответ

Попробуйте. Символ | - это или, также для таких поисков применяется [^&]+ - любые количеством больше 1, кроме &
console.log('http://site.loc/?search=abcdf&a=1'.match(/(\?|&)search=([^&]+)/)[2])

Hover на slick-слайдер

Для перелистывания слайдера использую cssEase:'linear' и когда навожу на элемент - появляется box-shadow, позиция мышки остается на слайде. Слайдер при этом продолжает скроллиться и box-shadow скроллится вместе со слайдером, но позиция мышки остается неизменной.
$(function() { $('.your-class').slick({ slidesToShow: 3, slidesToScroll: 1, autoplay: true, autoplaySpeed: 0, speed: 4000, pauseOnHover: false, cssEase:'linear' }); }); .your-class div { display: block; height: 100px; width: 800px; } .your-class div:hover { -webkit-box-shadow: 0 20px 55px 13px rgba(0, 0, 0, 0.2); -moz-box-shadow: 0 20px 55px 13px rgba(0, 0, 0, 0.2); box-shadow: 0 20px 55px 13px rgba(0, 0, 0, 0.2); }

aaaaa aaaaaaa
bbbbb bbbbbbb
ccccc ccccccc
ddddd ddddddd
eeeee eeeeeee
fffff fffffff
ggggg ggggggg
hhhhh hhhhhhh


Ответ

Во время анимации перемещения :hover не срабатывает. Браузер ждет ее окончания и эта проблема известна https://bugs.chromium.org/p/chromium/issues/detail?id=246304. Ничего тут не поделаешь.
Возможное решение: кастомно ставить класс .hover под элемент, над которым находится мышь:
$(function () { $('.your-class').slick({ slidesToShow: 3, slidesToScroll: 1, autoplay: true, autoplaySpeed: 0, speed: 4000, pauseOnHover: false, cssEase: 'linear' }); var lastCoordinates = [0, 0]; $(document).off('mousemove').mousemove(function (e) { lastCoordinates = [e.pageX, e.pageY]; }); $(document).on('touchmove', function (e) { //lastCoordinates = [e.pageX, e.pageY]; }); setInterval(function () { $('.hover').removeClass('hover'); var element = $(document.elementFromPoint(lastCoordinates[0], lastCoordinates[1])); if (element.closest('.your-class').length) { element.addClass('hover') } }, 100); }); .your-class div { display: block; height: 100px; width: 800px; } .your-class div.hover { -webkit-box-shadow: 0 20px 55px 13px rgba(0, 0, 0, 0.2); -moz-box-shadow: 0 20px 55px 13px rgba(0, 0, 0, 0.2); box-shadow: 0 20px 55px 13px rgba(0, 0, 0, 0.2); }

aaaaa aaaaaaa
bbbbb bbbbbbb
ccccc ccccccc
ddddd ddddddd
eeeee eeeeeee
fffff fffffff
ggggg ggggggg
hhhhh hhhhhhh

Как бесплатно попробовать azure?

Хочу начать работать с Azure, слышал что есть бесплатные способы это сделать.


Ответ

Дополню ответ Mikhail Vaysman:
При регистрации нового аккаунта дается 12500 рублей (эквивалент 200$, если Вы из России) на 30 дней
Внимание: для регистрации необходимо указывать номер телефона и номер банковской карты с не 0 балансом, т.к. Microsoft делает тестовое списание небольшой суммы (не более 30 рублей) и ее возврат через некоторое время.

Если данного времени не достаточно для тестирования всех возможностей сервиса, можно воспользоваться программой поддержки разработчиков от Microsoft Visual Studio Dev Essentials которая дополнительно предоставит 1600 рублей (25$) ежемесячно в течение года

Если у вас уже есть идея проекта, который хочется реализовать на платформе azure - можно попробовать воспользоваться программой спонсорской поддержки стартапов от Microsoft Bizspark, по данной программе каждому участнику стартапа будет предоставлено 9600 рублей (150$) в месяц для использования облачных сервисов в своей разработке, программа рассчитана максимум на 5 участников, длительность - 1 год.