Страницы

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

четверг, 10 января 2019 г.

разное поведение разметки для разных версий

К вопросам о поведении разметки в android - если в версиях после lolipop все работает как нужно, а до lolipop разметка становится корявой, как это исправить?
Конкретно - есть список recyclerView, в нем items, так вот в версии после 5 все выглядит, как нужно.
Если запускаю в версиях ниже (пробовал на 4.1.1 и 4.2), то индикатор, показывающий количество лайков съезжает влево.
Разметка одна и та же, как такие баги исправляются вообще?Писать каким-то образом отдельно под версии ниже 5-ой, я не понимаю.


Ответ

Под такие случаи пишут layout.xml с таким же названием только для версии API выше т.е. написав layout.xml с корректным видом для более нового API, кладем его в папку с названием layout-v19, все что выше 19 версии включительно будет отображаться как сказано в этом layout

Выделение активного пункта в NavigationView

Как выделить активный пункт меню в NavigationView? Пункты меню запускают Fragment, а сам NavigationView расположен в activity. NavigationView инициализировал сам, не из стандартного шаблона от Google.


Ответ

navigation = (NavigationView) findViewById(R.id.navigation_view); navigation.getMenu().getItem(0).setChecked(false); navigation.setNavigationItemSelectedListener(new navigation.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem menuItem) { int id = menuItem.getItemId(); switch (id) { case R.id.navigation_item: if (menuItem.isChecked()) { menuItem.setChecked(false); } else { menuItem.setChecked(true); } break; //и т.д. } return false;
menu xml:

... ....

Mysql найти записи которые имеют одинаковое значение поля до определенного символа

Как с помощью mysql найти записи которые имеют одинаковое значение поля до определенного символа?
Пример:
[id] [value] 0 11#1 1 12#44 2 11#12
Вывод:
[id] [value] 0 11#1 2 11#12
Символ конечно будет другой, как и другая структура таблицы.


Ответ

не совсем понятно что вы имеете ввиду. Какой должен быть результат, например, на таких данных:
id value 0 111#12313 1 22#fdsasd 2 22#qweert 3 33333#qwertrewq 4 111#werwr 5 22#qqqq 6 qweqweqw
Вот запрос, который подсчитывает для каждой строки количество повторений подстроки до символа #:
SELECT * FROM ( SELECT SUBSTR(value, 1, INSTR(value, '#')-1) as pref, COUNT(*) as cnt FROM tablename WHERE INSTR(value, '#') > 0 GROUP BY SUBSTR(value, 1, INSTR(value, '#')-1) /*HAVING COUNT(*) > 1*/ )T1 JOIN tablename T2 ON value LIKE CONCAT(pref, '#%')
На приведённых выше данных запрос выдаст:
id value pref cnt 0 111#12313 111 2 1 22#fdsasd 22 3 2 22#qweert 22 3 3 33333#qwertrewq 33333 1 4 111#werwr 111 2 5 22#qqqq 22 3
Если раскоментировать /*HAVING COUNT(*) > 1*/- то запрос выведет только те строки, префикс у которых неуникальный(повторяется как минимуму один раз).
UPD: условие соединения заменил на value LIKE CONCAT(pref, '#%'), чтобы при наличии индекса по value - он использовался.
При желании можно вообще обойтись без двух чтений из таблицы talename. В MySQL нет функции COUNT(*)OVER(PARTITION BY), однако это можно организовать с помощью переменных в запросе. В два этапа: сначала пронумеровать строки в каждой группе, потом найти максимум номера в группе.

Как устроена база данных например mysql?

Я так понимаю есть файл базы к примеру test.db
В test.db есть pages(страницы - я так понимаю это набор битов, разделение для быстрого доступа) по 8кб(допустим). Если файл базы огромный, как база быстро переключается на нужную страницу (на нужную область памяти).
К примеру есть текстовый файл с 1 миллион строк. Как мне быстро переключатся на нужную строку? к примеру сейчас я на 10 строке, оп уже на 200 тысячной и т.д.. без цикла? То есть как организован данный функционал для быстрого переключения на нужную страницу в базе? (или на строку в файле? если такое возможно)
Надеюсь поймете что я имею ввиду!


Ответ

Могу в общих чертах описать как базы хранит в файлах PostgreSQL.
Постгрес хранит таблицы и индексы в отдельных файлах. Максимальный размер файла = 1GB (также называется сегментом), если таблица/индекс выходит за эти пределы, то она дробится на несколько файлов по 1GB. В сегментах размещаются странички размером по 8kB (эта цифра, как и ограничение в 1GB может меняться на этапе компиляции). При работе с данными эти странички выгружаются в память и при необходимости повторного чтения берутся уже оттуда.
Непосредственно строки (tuples в терминологии постгреса) хранятся в этих страничках следующим образом:
В начале каждой странички имеется заголовок. Из интересного для нас на данный момент там хранится указатель на начало свободного места в страниче и указатель на его окончание. После загловка лежат идентификаторы строк, хранящихся в страничке. Каждый идентификатор представляет из себя указатель на начало строки и её размер. Постгрес наделяет каждую строку в базе уникальным идентификатором (CTID), он как раз и состоит из номера странички + идентификатора строки в ней. Это позволяет, имея CTID, быстро и без проблем найти строку на диске.
Сами данные заполняют страничку с конца. Это позволяет уменьшить фрагментацию страничек и более рационально упаковывать в них строки.
Вот приблизительное графическое представление:

Массовая смена автора документа

Подскажите как быть)
Предыстория:
У друга на работе уволился админ и на компе, буха, юрика и самого директора, изменил пользователя на Х%Й Булыжников или Пися Камушкин - не суть) Но обнаружили это через неделю или две, когда открыли документы doc, odt,xsl и прочие офисные, нажали файл - Свойства и там увидели сие чудо) а файлы они эти куда-то шлют и там через эту процедуру, даты сверяют в случае чего,)
Как можно массово такие офисные файлы перевладеть (сменить или убрать автора)?)
Руками долго (создать новый док, перекинуть все в него и сохранить - их там сотни документов) естественно, теперь Пользователь нормальный, но документы некоторые остались с пасхалкой)))
Подскажите, как под linux или windows можно автоматически поменять.
Думаю что скриптом можно, но не пойму как работать с api или самой libreOffice из консоли
Спасибо...
p.s. как выяснилось - админа очень обидели... и потом поняли что не правы, но было поздно)
Конвертировать в другой формат, в надежде смены автора так же безсмысленно
libreoffice -env:UserInstallation=file:///home/firefedot/.config/libreoffice-alt --headless --convert-to odt *.doc
В итоге остался тот же автор создания документа и те же авторы изменений.


Ответ

Спасибо @Qwertiy за подсказку.
В общем пока что вариант такой нашел. Сначала приводим все нужные файлы к типу odt, таким образом
libreoffice -env:UserInstallation=file:///home/firefedot/.config/libreoffice-alt --headless --convert-to odt *.doc
Затем можно скриптом, а можно и руками, делаем так. Распаковывем наш файл ODT в папку
unzip file.odt -d folder
После этого ищем и заменяем нужного/ненужного автора
grep NONAMES meta.xml --color # Или если не знаем имени, то grep creator meta.xml --color
И мы увидим нужное нам, оно будет подсвечено)
Заменяем все что нужно
sed -i 's/NONAMES/MyName/g' meta.xml
Затем, мы приводим завершающие действия. Запаковываем все обратно, в два этапа, для правильной структуры нового файла
1:
cd folder zip -0 -X file.odt mimetype
2:
zip -r file.odt * -x mimetype
После этого файл открывается без ошибки и если открыть меню Файл-Свойства, мы увидим того автора,которого внесли.
Осталось проверить как это все работает именами файлов содержащие пробелы.
p.s. если @Qwertiy возражает, то могу все это передать ему в ответ.

Сериализация в С++

Прошу дать ссылки, или, если есть желание, рассказать вкратце о красивом, удобном способе сериализации полей класса в C++. Приведу пример (не уверен, что так можно, но хотелось бы) - использовать свойства, аналогичные свойствам в C#, перед полями, которые будут учавствовать в сериализации (но: рефлексия ?), все автоматически упаковывается в JSON/XML (если это важно, то JSON меня интересует в большей степени), аналогично читается из JSON/XML и инициализирует соостветствующие поля объекта.


Ответ

Универсального решения нет - и быть не может без рефлексии - которая будет - возможно - только в следующих версиях плюсов - да и с ней - если будут накладные расходы - универсального решения не будет. Вы можете выбирать из библиотек. По скорости или удобству использования.
"свойства, аналогичные свойствам в C#, перед полями" реализуются всеми этими либами через макросы (слегка приврал), многое из того, что раньше можно было достичь только макросами сейчас можно достижимо средствами шаблонов C++, но:
вот пример использования boost::serialization c макросами. Пример добавления рефлексии с шаблонами и макросами. RTTI с макросами
Сами по себе макросы - зло, но бывают и необходимым злом.
я для себя взял rapidjson (пушо очень быстрая) и сделал вокруг нее пару обвязок типа stringValue / intValue. В принципе, достаточно удобно пока.
По поводу бустов: попользуйтесь, наверняка будет полезно. Выпиливать куски не надо, на рантайм это не повлияет, может быть только на время компиляции. Если подойдет другая либа для json/xml (POCO) например, берите ту, что вам удобнее в использовании. Вам главное инкапсулировать как можно больше, чтобы вы могли сменить потом либу, а не ловить ее вызовы по всему коду

Вызов статической переменной из другой функции

Необходимо обратиться к статической переменной из другой функции. Пример в коде:
void First(void) { static int a = 5; }
void Second(void) { //Тут необходимо узнать значение переменной 'a' из функции 'Firts' }


Ответ

Напрямую - никак. Область видимости статической переменной внутри функции ограничена самой этой функцией. Можно извернуться как-то так:
int *First( void ) { static int a = 0; return &a; } void Second( void ) { my *First_A_Pointer = First(); }
Но сама потребность в подобных извращениях говорит о том, что архитектура кода крайне непродумана, и её нужно менять. Без вариантов.

telegram-bot в общем чате

Сделал простого telegram-бота:
import telebot @bot.message_handler(content_types=["text"]) def repeat_all_messages(message): if (message.text.split(" ")[0].upper() == 'BOT,'): bot.send_message(message.chat.id, 'I\'m here')
Все отлично работает, но когда добавляю его в групповой чат, то он молчит. Подскажите, как сделать его адаптированным к групповым чатам ?


Ответ

Вариантов несколько:
Можно обращаться к боту через слеш / - /YourMessage, если в группе несколько ботов, то с упоминанием его юзернейма - /YourMessage@YourBotName Можно задать боту список команд с помощью @BotFather, тогда при вводе слеша пользователь увидит список всех доступных команд и сможет выбрать нужную. Можно отключить privacy mode, тогда к бот будет получать все сообщения от группы, кроме сообщений от других ботов. По умолчанию privacy mode включен. Можно сделать бота администратором группы, что так же позволит получать все сообщения от группы, кроме сообщений от других ботов.
What messages will my bot get? Your bot will receive all messages from users in one-on-one chats. Privacy mode only applies to messages in groups (or supergroups). Privacy mode is always disabled if your bot is an admin in the group. For supergroups, privacy mode is set to what your bot was using when it joined the group — if you change it later, you'll need to remove the bot and add it again for changes to take effect. By default, your bot runs in privacy mode and only sees the following messages in groups (or supergroups): Replies to the bot's own messages (messages sent via a custom keyboard are always a reply to the bot). Commands from users meant for your bot (e.g. /start@YourBot). General commands from users (e.g. /start) if your bot was the last bot that sent a message to the group. Service messages (e.g. when somebody leaves or joins a group, group name or photo changes, etc.). If your bot is an admin or if privacy mode is disabled, your bot will get all messages sent to the group, except for messages from other bots.
Ссылка

Как передавать данные между Activity? [дубликат]

На данный вопрос уже ответили: Передача данных между Activity 2 ответа Есть long timefinal - время, которое нужно передать следующей Activity в TextView
Как правильно это сделать?


Ответ

Через интент:
FirstActivity.java
...
Intent intent = new Intent(this, SecondActivity.class); intent.putString("tag", timefinal); startActivity(intent);
...
SecondActivity.java
@Override protected void onCreate(Bundle savedInstanceState) { String timefinal = getIntent().getString("tag"); textView.setText(timefinal); }

System.OutOfMemoryException при добавлении элемента в словарь

Возникла проблема с ограничениями памяти для приложения. Из того что я понял: для приложения или под созданный объект (в моем случае это словарь) выделяется не больше 2Гб памяти. Хотелось бы создать словарь, который мог бы быть размера как минимум свободной части оперативной памяти. Как это сделать?
StackTrace исключения:
в System.Collections.Generic.Dictionary`2.Resize(Int32 newSize, Boolean forceNewHashCodes) в System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) в System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)


Ответ

Сперва об OutOfMemoryException. Вопреки расхожему мнению, это исключение не означает, что закончилась память. Оно означает, что отсутствует требуемый непрерывный объем памяти. При этом свободной памяти еще может быть много, просто она фрагментирована. Например, CLR хочет выделить участок в 100 Мб, но есть только 20 свободных участков по 50 Мб. Свободная память есть, при этом OutOfMemoryException тоже есть.
Со словарем проблема заключается в том, что для изменении его размера требуется, грубо говоря, в два раза больше памяти, чем он занимает. Т.е. если на данный момент ваш словарь полностью заполнен и занимает 100 Мб (сам объект словаря, ключи/значения при этом могут храниться отдельно), то при добавлении очередного элемента нужно увеличить размер словаря, и на это требуется выделить 200 Мб памяти.
Теперь про ограничения. 2 Гб -- это объем памяти, выделяемый для 32-битного приложения (2^32). Для того, чтобы получить возможность кушать больше памяти (2^64), приложение должно быть 64-битным. При этом необходимо также включить опцию , которая позволит иметь массивы объемом больше 2 Гб.
Также вам стоит посмотреть внимательнее на ваш алгоритм, возможно его можно пересмотреть в сторону уменьшения потребления памяти.
Резюмируя в порядке важности:
Пересмотрите алгоритм (можете выложить его здесь отдельным вопросом и вам постараются подсказать). Сделайте приложение 64-битным и включить опцию

Как подключить 2-й выделенный IP

Приветствую, есть VDS и 2 выделенных IP, один давали с покупкой VDS (и сейчас доступ по нём открыт), а 2-й купил дополнительно.
Как мне подключить 2-й IP адрес к этому VDS, что бы при запросе на него открывались файлы, к примеру, из директории /var/www/site2/ не подключая к доменам? И доступ к директориям должен быть непосредственно по IP.
Спасибо.


Ответ

Для начала вам нужно назначить этот IP вашем сетевому интерфейсу. Как это делается - зависит от дистрибутива. Это либо файл /etc/network/interfaces для Debian/Ubuntu, либо /etc/sysconfig/network-scripts/ifcfg-* для CentOS/Fedora. Вы же знаете какая у вас ОС? Посмотрите её документацию.
Далее вам нужно сказать про этот IP веб-серверу. Если в директории Listen не указан конкретный IP - то Apache слушает все имеющиеся адреса. Если вас это устраивает - оставляйте, в противном случае впишите лишь новый адрес, если вы хотите что бы обращения принимались лишь на него. Далее - у вас уже есть VirtualHost который настроен на директорию /var/www/site2/ или нет? Если нет, создайте его, указав примерно такое:
> DocumentRoot "/var/www/site2/" <остальные_директивы_по_вкусу>
В конце не забудьте применить новую конфигурацию.

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

Нужно вывести информацию с db_order, если нету ни одного повторения значения с db_order.id в таблице db_ips.order_id
Сами таблицы:
db_ips
db_order
Спасибо.


Ответ

Если я правильно понял ваш вопрос, то как то так:
SELECT db_order.* FROM db_order LEFT OUTER JOIN db_ips ON db_order.id = db_ips.order_id WHERE db_ips.order_id IS NULL;

Подзапрос SELECT

Есть таблица результатов экзаменов по русскому языку и математике:
declare @Results Table ( SchoolID nvarchar(200), ParticipID nvarchar(200), SubjectCode int, TestResult5 int )
--subjectcode: 1-русский язык, 2-математика
insert into @Results VALUES ('0001', 'Шахабов_Адам', 1, 4), ('0001', 'Асвадов_Аюб', 1, 3), ('0001', 'Майрукаев_Бекхан', 1, 3), ('0001', 'Шахабов_Адам', 2, 3), ('0001', 'Асвадов_Аюб', 2, 4), ('0001', 'Майрукаев_Бекхан', 2, 5), ('0002', 'Цуригова_Зайнап', 2, 5), ('0002', 'Майрукаев_Роза', 2, 4), ('0002', 'Муциев_Адлан', 2, 3), ('0002', 'Цуригова_Зайнап', 1, 3), ('0002', 'Майрукаев_Роза', 1, 4), ('0002', 'Муциев_Адлан', 1, 5)

Условие: Необходимо извлечь список школ (SchoolID), у которых число участников, получивших отметку 3 по русскому языку, больше 1.
Как я это делаю:
select schoolid from
(select schoolid, SUM(CASE WHEN subjectcode = 1 and testresult5 = 3 then 1 else 0 end) c from @Results group by schoolid) temp_table
where c > 1

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


Ответ

Вам поможет HAVING:
SELECT schoolid, COUNT(ParticipID) FROM @Results WHERE subjectcode = 1 AND testresult5 = 3 GROUP BY schoolid HAVING COUNT(ParticipID) > 1
http://sqlfiddle.com/#!9/fe6b2/1/0
https://ru.wikipedia.org/wiki/Having_(SQL)

Корректное отображение даты из Unix UTC

От сервера приходит дата в формате "Time of data calculation, unix, UTC" и значение равно, например 1473777482.
В приложении делаю обработку для более читабильного формата и присваиваю значение в поле TextView:
Date date = new Date(resp.getDt() * 1000) mDateTextView.setText(new SimpleDateFormat("EE, dd MMMM yyyy, HH:mm").format(date));
И вроде все ничего, но только отображается 14 сентября и время 2 часа (ночи). Каким образом можно привести с актуальному текущему времени по Мск.?
В теории можно просто отнять от текущего времени константу, которая равна разнице, но на мой взгляд это не очень корректно, да и скорее всего существует какой то способ, но я его не обнаружил.


Ответ

Просто установите нужную зону так:
SimpleDateFormat format = new SimpleDateFormat("EE, dd MMMM yyyy, HH:mm") format.setTimeZone(TimeZone.getTimeZone("UTC"));

Получить кнопку,на которой находится курсор

Добрый день. Несколько кнопок размещены на TableLayoutPanel. Необходимо при наведении мыши на кнопку выводить в лейбле(расположенном ниже) её Tag. Не понял, как использовать GetChildAtPoint, подскажите пожалуйста.


Ответ

Зачем использовать GetChildAtPoint, если есть событие MouseEnter? Можно задать для любого количества кнопок один и тот же обработчик (в коде или в дизайнере), примерно такого вида:
private void TableLayoutPanelButton_MouseEnter(object sender, EventArgs e) { var tag = ((Button)sender).Tag; // делаем что нужно }

График на CSS. Возможно ли?

Добрый день! Подскажите, пожалуйста, возможно ли выполнить такой график на css?


Ответ

Если все же на CSS
*{ box-sizing: border-box; } .graph { position: relative; width: 200px; height: 400px; } .circle { position: relative; width: 200px; height: 400px; overflow: hidden; } .box { position: absolute; transform-origin: 50% 50%; } .item { height: inherit; border: 20px solid; } .count-list { list-style-type: none; padding: 0; margin: 0; } .count-list li { position: absolute; top: 0; right: -20px; font-family: sans-serif; } .count-list li:nth-of-type(1){ top: 0; color: gold; } .count-list li:nth-of-type(2){ top: 30px; color: orangered; } .count-list li:nth-of-type(3){ top: 60px; color: darkturquoise; } /* ------ 1 ------- */ .b-1 { top: 0; left: 0; width: 400px; height: 400px; transform: rotate(0deg); } .b-1 .item { width: 200px; border-color: gold; border-right: none; border-bottom-left-radius: 200px; border-top-left-radius: 200px; } /* ------ 2 ------- */ .b-2 { top: 30px; left: 30px; width: 340px; height: 340px; transform: rotate(30deg); } .b-2 .item { width: 170px; border-color: orangered; border-right: none; border-bottom-left-radius: 170px; border-top-left-radius: 170px; } /* ------ 3 ------- */ .b-3 { top: 60px; left: 60px; width: 280px; height: 280px; transform: rotate(60deg); } .b-3 .item { width: 140px; border-color: darkturquoise; border-right: none; border-bottom-left-radius: 140px; border-top-left-radius: 140px; }

  • 1
  • 2
  • 3

Но уже лучше тогда использовать для такого препроцессоры. Мой код на CODEPEN
А еще лучше не мудрить, а рисовать все это svg.

Сглаживание анимации фона

Есть такой блок с фоном и эффектом:
html, body { margin: 0; padding: 0; width: 100%; height: 100%; } .box { width: 100%; height: 100%; background: url(http://www.nasa.gov/sites/default/files/thumbnails/image/potw1441a.jpg) center no-repeat; -webkit-background-size: 150%; background-size: 150%; transition: all 5.27s ease-in-out; } .box:hover { -webkit-background-size: 100%; background-size: 100%; }


При наведении на блок, фон начинает дергаться и как-то с задержками изменяться.
Это можно как-то исправить (сгладить), если применять transition именно к background-size (со 150% до 100%)?
P.S: С transform: scale; я знаю решение, спасибо!


Ответ

Вы видите «дергание», потому что используете очень большое время анимации. Если поставить 1 секунду, анимация проходит гладко: https://jsfiddle.net/0c4mqLp8/
Экспериментируйте с параметрами: all 5s ease или all 1s ease-in-out, например. У меня оба варианта работают гладко.
Почему происходит скачки: ваша картинка выровнена по-центру блока. Изменяя масштаб, ширина картинки меняется то на четное, то на нечетное значение. Пиксель — самая маленькая единица измерения: центр делит картинку пополам и при четном значении картинка делится поровну, а при нечетном остается 0.5 пикселей, которые и придают дергание фоновому изображению — оно перемещается то влево, то вправо.

Ограничение точками число

Как сделать так, чтобы число ограничивалось каждые 3 цифры точками, например, 123.745.126 и если дробное число то, 123.745.126.74?


Ответ

Это делается так
#include #include #include
struct Facet: std::numpunct { char do_thousands_sep() const { return '.'; }
std::string do_grouping() const { return "\3"; } };
int main() { std::cout.imbue(std::locale(std::locale(), new Facet)); std::cout << 1000000000; }
numpunct locale imbue Если вам нужно это число сохранить в строку, используйте stringstream

Как в java сделать comit в sql если я хочу закомитить много объектов?

Делаю так:
PreparedStatement ps = conn.prepareStatement( "INSERT INTO mydbcall1.Call0 (date,direction,operator,abonentTel,duration,coast1,coast2,corpPhone)" + " VALUES(?, ?, ?, ?, ?, ?, ?, ?)"); try {
ps.setDate(1, new java.sql.Date(call.date.getTime()) ); ps.setString(2, call.direction); ps.setString(3, call.operator); ps.setString(4, call.abonentTel); ps.setInt(5, call.duration); ps.setDouble(6, call.coast1); ps.setDouble(7, call.coast2); ps.setString(8, call.corpPhone); ps.executeUpdate(); // for INSERT, UPDATE & DELETE
} finally { ps.close(); }
метод для 3000 объектов работает больше 1.5 минут.


Ответ

Не создавайте PreparedStatement каждый раз заново. Преимущество PreparedStatement перед обычным Statement именно в том, что можно его заранее отправить на сервер БД для компиляции и переиспользовать повторно. Отправляйте вставки пакетами (batch). Вероятно, вам придется подобрать оптимальный размер пакета. Используйте явное управление транзакцией. По-умолчанию транзакция завершается на каждый запрос к БД (autoCommit = true).
Вот пример с применением этих трех рекомендаций (используется try-with-resources):
private static final String INSERT_STATEMENT = "INSERT INTO mydbcall1.Call0(date,direction,operator,abonentTel,duration,coast1,coast2,corpPhone) VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
// ....
try ( Connection connection = database.getConnection(); PreparedStatement ps = connection.prepareStatement(INSERT_STATEMENT); ) { int i = 0; connection.setAutoCommit(false) for (Call call : calls) { ps.setDate(1, new java.sql.Date(call.date.getTime()) ); ps.setString(2, call.direction); ps.setString(3, call.operator); ps.setString(4, call.abonentTel); ps.setInt(5, call.duration); ps.setDouble(6, call.coast1); ps.setDouble(7, call.coast2); ps.setString(8, call.corpPhone); // ...
ps.addBatch(); i++;
if (i % 1000 == 0 || i == calls.size()) { ps.executeBatch(); // ограничиваем размер одного пакета тысячей вставок } } connection.commit(); } catch(SQLException e) { connection.rollback(); }

Изменить размер массива динамически

Например есть такой массив, как изменить его размер с 4 на другое число?
int[] array = new int[4];


Ответ

Вы подходите неправильно. Если вам нужно менять размер контейнера, вы должны вместо массива использовать List
Вы не сможете изменять размер, добавляя неинициализированные элементы, но вы сможете добавить элемент в конец при помощи Add, в начало или середину при помощи Insert, или удалять по индексу при помощи RemoveAt

MinGW или Cygwin?

Раньше просто компилировал с помощью g++ на Ubuntu, вытягивая компилятор с помощью пакетного менеджера:
$ sudo apt-get install g++ $ g++ -o main.a main.cpp
Или на Windows с помощью различных IDE, внутри которых, как мне говорили, стоит MinGW.
Сейчас хочется просто, используя внутреннюю консоль в Окнах, компилировать нативно под них самих же. Почитал про Cygwin и про MinGW, понял, тащемта, что к чему, но остались пробелы - не совсем ясно что мне нужно.
Можно ли подробно, а лучше очень просто, узнать о каждой возможности скомпилировать под Окна?


Ответ

Cygwin - это попытка перенести UNIX окружение в Windows, а MinGW (или современный вариант MinGW-w64) сосредоточен только на компиляторе GCC
Далее, при компиляции программы с помощью Cygwin, по условиям его лицензии вы будете линковаться с его динамической библиотекой cygwin1.dll и таскать её всюду за собой, в то время, как с MinGW, вы будете зависеть только от стандартных MSVC библиотек (по-умолчанию от msvcrt.dll).
Поскольку MinGW это только компилятор, то есть отдельный проект - MSYS2 который поставляет облегчённую/минимальную версию UNIX окружения в достаточном объёме, чтобы вести разработку почти как в UNIX (там есть bash, git, curl и т.д.). Причём, утилиты для MSYS2 собираются при помощи MinGW.
Про отличия MinGW от Cygwin можно ещё почитать:
в wiki: https://ru.wikipedia.org/wiki/MinGW в английской версии SO: What is the difference between Cygwin and MinGW? ну, и загуглить: Cygwin vs. MinGW

Синтаксис инициализации const членов класса

Есть класс
class object { public: object(); private: const double mass; };
Инициализация const double mass в конструкторе отрабатывает только так:
object::object(): mass(1) { }
Почему не проходит такой вариант?
object::object() { this->mass = 1; }
И как в таком случае инициализировать const члены класса, которые должны предварительно высчитываться относительно входных параметров конструктора?
Какие варианты в C++ удобны для объявления/инициализации const членов класса?


Ответ

Когда выполняется тело конструктора, то все члены данных объекта уже созданы. Поэтому в этом конструкторе
object::object() { this->mass = 1; }
в предложении
this->mass = 1;
применяется оператор присваивания, который нельзя использовать с константными объектами.
Если вам нужно определить значение константного члена данных на основе некоторых вычислений, то в качестве инициализатора используйте некоторую, например, статическую функцию - член класса.
object::object( some_argument ): mass( some_function( some_argument ) ) { }
Аргументами функции не обязательно должны быть аргументы конструктора. Можно использовать статические члены данных класса, не статически члены данных, которые уже были инициализированы в списке инициализации (лги в объявлении класса должны предшествовать, или объекты, которые находятся в области видимости определения конструктора.
Ниже показан пример
#include
class Object { public: Object( double x ) : x ( 2 * x ), mass( init( this->x ) ) { }
double get_mass() const { return mass; }
private: double x; const double mass; static double init( double x ) { return x < 0 ? -x / 2 : x; } };
int main() { Object obj( 10 );
std::cout << obj.get_mass() << std::endl;
return 0; }