Страницы

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

четверг, 18 апреля 2019 г.

Регистры (теоретический вопрос)

Здравствуйте, извиняюсь за возможно глупый вопрос, но скажите пожалуйста где располагаются регистры eax, ebx, ecx, edx, edi, esi, в оперативной памяти или процессоре?
Сам вопрос появился после того как я подумал, что если я не чего не путаю, то регистры всегда вроде-бы располагались в процессоре (ну если верить книжкам), но я не могу понять одного, как десятки процессов используют эти регистры грубо говоря асинхронно, процессор же не может разорваться на каждый процесс. Ну и вот с этого момента мне стало очень интересно как так может быть и я решил спросить у профессионалов.


Ответ

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

в грубом приближении:
внутри процессора есть таймер, который время от времени посылает процессору сигнал («прерывание»), при получении которого процессор сохраняет текущее содержимое всех регистров в стек (находится в оперативной памяти, обычно каждый процесс имеет собственный стек; а сохраняются туда регистры не только с данными, но и со всякой контрольно-управляющей информацией, типа ip — instruction pointer — адресом следующей выполняемой команды) и передаёт управление по адресу обработчика данного прервывания (обработчик обычно реализован в ядре операционой системы).
обработчик выбирает, какой процесс следует запустить следующим (какому процессу отдать очередной «квант времени»), и даёт процессору команду «загрузить в регистры то, что сохранённо там-то».
восстановленный же из стека процесс продолжает работу «как ни в чём не бывало», до следующего срабатывания таймера.

Класс ObservableCollection и функция IndexOf

Добрый день столкнулся с такой проблемой: функция IndexOf класса ObservableCollection всегда возвращает -1. Вот код:
ObservableCollection FilterMask = new ObservableCollection(); foreach(Worker w in ListWorker) { if(w.Directions.Count == 0) continue; Item ForFilter = new Item() { Text = w.Directions[0], IsSelected = true }; if (FilterMask.IndexOf(ForFilter) == -1) FilterMask.Add(ForFilter); }
Пример класса Item:
public class Item : INotifyPropertyChanged { string _Text; public string Text { get { return _Text; } set { _Text = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Text")); } }
bool _IsSelected; public bool IsSelected { get { return _IsSelected; } set { _IsSelected = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsSelected")); } }
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion }
В FilterMask появляются дубликаты, чего не должно быть согласно коду=)


Ответ

Разумеется, возвращает -1. Ты создаёшь новый объект класса Item и ищешь его в коллекции. Он туда ещё не добавлен. Если ты хочешь, чтобы твой код работал, перегрузи в Item методы Equals и GetHashCode. Или полноценно реализуй интерфейс IEquatable

о принципе работы into into

Здравствуйте. Не могу понять, когда именно данные сохраняются в ws ?
string[] websites = { "hsNameA.com", "hsNameB.net", "hsNameC.net", "hsNameD.com", "hsNameE.org", "hsNameF.org", "hsNameG.tv", "hsNameH.net", "hsNameI.tv" };
var webAddrs = from addr in websites group addr by addr.Substring(addr.LastIndexOf('.')) into ws where ws.Count()>2 select ws;
После группирования домена или в каждом шагу ? Не могу понять, какой последовательностью работают алгоритмы когда используются groupby и into.


Ответ

SQL-подобный синтаксис разворачивается в последовательный вызов методов расширений LiNQ. В некоторых случаях такой синтаксис легче читается, чем длинные цепочки вызова методов.
Ваш запрос можно переписать так:
var groups = websites.GroupBy(addr => addr.Substring(addr.LastIndexOf('.'))); var webAddrs = groups.Where(ws => ws.Count() > 2);
Таким образом видно, что сначала формируются все группы и, только после этого, происходит отбор нужных групп.
Если написать последовательность вызова одной строкой (без промежуточной переменной groups) и посмотреть на результат компиляции в IL-код (например в LINQPad), вы убедитесь, что это одно и тоже.

Scala. Список футур. Выполнение шаг за шагом

Хола, коллеги! У меня есть список некоторых сущностей. Они могут быть вложены друг в друга. Например:
case class Entity(id: Long, parentId: Long)
val list = List( Entity(1,0), Entity(2,1), Entity(3,2), Entity(4,1), Entity(5,0) )
Мне нужно добавить их в БД. Мой сервис:
val listOfFutures = list map createEntity // createEntity - мой метод, // который добавляет сущность в БД. // Возвращает Future[Entity] Future.sequence( listOfFutures ) map { _ => println("Ok!") }
Проблема в constraints(Как их по-русски назвать?). Получаю ошибку:
Create failed. No such parent 1 entity exists.
Я думаю, что проблема в том, что метод createEntity выполняется параллельно. Как заставить этот код выполняться последовательно, сущность за сущностью?


Ответ

Future считается монадой, так как у неё есть последовательный flatMap
list.foldLeft(Future.successful(()))(( prevF, entity) => prevF .flatMap( _ => createEntity(entity)) .map( _ => ()) )
Аналогичный код, используя for-comprehension:
list.foldLeft(Future.successful(()))(( prevF, entity) => for { _ <- prevF _ <- createEntity(entity) } yield () )
Объяснение:
val entity = Entity(0, 1) createEntity(entity).map( _ => println("Ok!"))
Метод map запоминает полученную функцию и выполняет её после того как получит успешный результат Future
Meтод flatMap работает также, только ожидает что полученная функция тоже будет возвращать Future
createEntity(entityOne).flatMap( _ => createEntity(entityTwo))
Таким образом мы соединяем две Future последовательно, т.е. вторая вызовется только после успешного выполнения первой.
Отсюда очевидно что мы можем выстраивать длинные последовательные цепочки.
createEntity(entityOne) .flatMap( _ => createEntity(entityTwo)) .flatMap( _ => createEntity(entityThree)) .flatMap( _ => createEntity(entityFour))
А результатом будет новая Future. Ок, а как поступить если у нас есть список Future? Так же как мы бы поступили бы например с числами.
val listNumbers = List(1, 2, 3, 4, 5)
val zeroNumber = 0 def joinNumbers(a: Int, b: Int): Int = a + b
listNumbers.foldLeft(zeroNumber)(joinNumbers)
Почему foldLeft, а не map? Потому что прибавляем по очереди, и нам нужна сумма предыдущих чисел. Зачем нужен zeroNumber? Ну а вдруг список пустой - вернем 0.
Теперь с Future:
val listEntities: List[Entity] = ???
val zeroFuture = Future.successful(()) def joinFuture(prevF: Future[Unit], entity: Entity): Future[Unit] = prevF .flatMap(_ => createEntity(entity)) // тут вторая Future .map( _ => ())
listEntities.foldLeft(zeroFuture)(joinFuture)
Следующий createEntity выполняется после предыдущих. Зачем нужен zeroFuture - ну а вдруг список пустой. UPD:
Попробую подробней расписать почему foldLeft, а не map. Сначала взглянем на map
val listOfFutures = list.map( entity => createEntity(entity))
map просто проходит по листу и вызывает создание Энтити. Он не ждёт пока создание завершится, он просто создаёт новую Future и идёт дальше к следующему элементу листа.
Т.е. на каждой итерации нам нужно "нечто" что будет знать о том что на предыдущем шаге Энтити создался:
val listOfFutures = list.map( entity => val prevEntityWasCreated = ??? // что-то, что знает о предыдущем Энтити
// flatMap заставляет выполнятся ПОСЛЕ prevEntityWasCreated.flatMap(_ => createEntity(entity)) )
Т.е. проходимся по списку и на каждом этапе ждем пока завершиться предыдущий. Что-то подобное нам надо, верно?
Точнее такое:
val listOfFutures = list.map( (prevEntityWasCreated, entity) =>
prevEntityWasCreated.flatMap(_ => createEntity(entity)) )
Супер. Второй энтити ждет когда создастся первый, третий ждёт когда создастся второй. А чего ждёт первый? Надо создать пустую Future специально для первой этнити:
val zeroFuture = Future.successful(()) val listOfFutures = list.map(zeroFuture)( (prevEntityWasCreated, entity) =>
prevEntityWasCreated.flatMap(_ => createEntity(entity)) )
Всё отлично, только тип не совпадает:
val zeroFuture: Future[Unit] = Future.successful(()) val foo: Future[Entity] = prevEntityWasCreated.flatMap(_ => createEntity(entity))
Просто добавим map и изменим тип на одинаковый
val zeroFuture: Future[Unit] = Future.successful(()) val foo: Future[Unit] = prevEntityWasCreated.flatMap(_ => createEntity(entity)).map( _ => ())
Последнии штрих - переименовать новую функцию в foldLeft
list.foldLeft(Future.successful(()))(( prevF, entity) =>
val foo: Future[Unit] = prevF .flatMap( _ => createEntity(entity)) .map( _ => ()) // возвращаем Future для следующего элемента foo )

Утечка памяти при многократном запуске потока

Доброго (CurrentTime) ,Столкнулся со странностью при многократном создании потока и по завершению исполнения озу не освобождается, можете рассказать что тут происходит, прошу извинений за вопрос тк новичок?
public class MainClass {
public static void main(String[] args) throws InterruptedException {
int i = 0; while (i < 100000) { TestThread test = new TestThread(); test.start(); i++; }
System.gc(); Thread.sleep(8000);
}
}
Класс TestThread
public class TestThread extends Thread {
public void run() {
// Пустой
}
}


Ответ

Несколько возможных причин для такого поведения:
Потоки не завершились на момент вызова System.gc
Потоки, хоть они ничего и не делают, требуют выделения ресурсов для запуска. Вы запускаете один за другим 100000 потоков, а затем вызываете сразу gc не дожидаясь их завершения. Часть потоков может быть не завершена на этот момент. Дождаться завершения работы потока можно с помощью Thread.join
Вызов System.gc не обязательно запускает сборщик мусора.
Из документации к System.gc
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. ... Вызов метода предлагает виртуальной машине Java приложить усилия для обработки неиспользуемых объектов, чтобы сделать память, которую они занимают, доступной для быстрого повторного использования. ....
В общем, это рекомендация, которая не гарантирует сборку мусора. Сборка мусора произойдет когда виртуальная машина посчитает нужным. Можете еще почитать ответ на вопрос: «Как часто надо вызывать сборщик мусора?»
Сборка мусора не обязательно освобождает память для ОС.
Даже если сборка мусора запустится, нет никакой гарантии, что освобожденная память будет возвращена ОС для использования в других процессах.
Освобождение памяти и выделение ее заново — ресурсоемкие задачи, которые могут оказать влияние на производительность клиентского (Вашего) кода. Поэтому разработчики JVM предусматривают сложные алгоритмы сборки мусора с минимальным влиянием на исполнение. В зависимости от настроек памяти JVM и используемого сборщика мусора память может быть сохранена для повторного использования Java (на очистку вообще не тратятся ресурсы) либо возвращена частично до определенного процентного порога (перераспределение памяти происходит в ограниченных масштабах).
Подробнее о разных сборщиках мусора смотрите в документации к используемой Вами версии JVM. Можете также ознакомиться с обзорными статьями по теме:
Статьи на сайте Oracle: Java HotSpot Garbage Collection Теория и практика Java: Сборка мусора в HotSpot JVM серия статей «Дюк, вынеси мусор!» на Хабре.

Сериализация сложного JAVA объекта в JSON

Добрый день подскажите как сериализовать в JSON объект Files? Используя метод toJsonString сериализуются только поле nameDirectory, а поле pool выводится в виде хеша?
import org.json.simple.JSONValue; import org.json.simple.JSONArray; import org.json.simple.JSONObject;
public class Files {
public Map pool;
public String nameDirectory;
public String toJsonString(){ JSONObject JSobj = new JSONObject(pool); JSobj.toJSONString(); } }
public class File { String PathFile; ArrayList Records; boolean PutInEnd; }
public class Record {
private String recordname; private String status; private int countExecution; }


Ответ

Для таких целей есть специальные библиотеки - Jackson и Gson
import java.io.File; import java.io.IOException; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap;
import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.JsonMappingException;
class Record { // Поле name и так находится в Record, // называть его recordname - это лишнее private String name; private String status; private int executionCount;
public Record() {}
public Record(String name, String status, int executionCount) { setName(name); setStatus(status); setExecutionCount(executionCount); }
public void setName(String name) { this.name = name; }
public String getName() { return name; }
public void setStatus(String status) { this.status = status; }
public String getStatus() { return status; }
public void setExecutionCount(int executionCount) { this.executionCount = executionCount; }
public int getExecutionCount() { return executionCount; } }
// Плохая идея использовать имена классов // входящих в стандартную библиотеку class SomeFile { private String path; // Имена полей должны начинаться со строчной буквы private List records; private boolean putInEnd;
public SomeFile() { records = new ArrayList<>(); }
public SomeFile(String path, boolean putInEnd) { this(); setPath(path); setPutInEnd(putInEnd); }
public void setPath(String path) { this.path = path; }
public String getPath() { return path; }
public void setPutInEnd(boolean putInEnd) { this.putInEnd = putInEnd; }
public void addRecord(Record record) { records.add(record); }
public List getRecords() { return records; } }
class SomeFiles { private String name; private Map pool;
public SomeFiles() { pool = new HashMap<>(); }
public SomeFiles(String name) { this(); setName(name); }
public void setName(String name) { this.name = name; }
public String getName() { return name; }
public void putSomeFile(String name, SomeFile someFile) { pool.put(name, someFile); }
public Map getPool() { return pool; } }
public class App { public static void main(String[] args) { SomeFile f = new SomeFile("/root/secret.txt", false); f.addRecord(new Record("Some Record", "Some status", 42)); f.addRecord(new Record("Another Record", "Same status", 0));
SomeFiles sf = new SomeFiles("Some Files"); sf.putSomeFile("Some File", f);
ObjectMapper mapper = new ObjectMapper(); // Для вывода с отступами mapper.enable(SerializationFeature.INDENT_OUTPUT);
try { // Здесь происходит самая главная магия mapper.writeValue(new File("some_files.json"), sf); } catch(JsonGenerationException exc) { exc.printStackTrace(); } catch(JsonMappingException exc) { exc.printStackTrace(); } catch(IOException exc) { exc.printStackTrace(); } } }
Получится такое:
{ "name" : "Some Files", "pool" : { "Some File" : { "path" : "/root/secret.txt", "records" : [ { "name" : "Some Record", "status" : "Some status", "executionCount" : 42 }, { "name" : "Another Record", "status" : "Same status", "executionCount" : 0 } ] } } }

SQL Server Management Studio (SSMS) не видит созданные таблицы

Недавно сел изучать БД и столкнулся с проблемой, что в созданные таблицы я не могу ничего добавить и удалить их (потому что SSMS не видит эти объекты)

Использую я Sql Server 2014 + SSMS версии 17 года (возможно проблема здесь ,но я не понимаю как исправить)


Ответ

SSMS не понимает в какой базе ему искать таблицу Customers
1. Указать явно какую БД использовать с помощью use
Добавить в начало запроса
Use test_db;
2. Указать полный путь к БД в запросе
drop table [test_db].[dbo].[Customers]
3. Указать БД test_db по-умолчанию для вашего пользователя
Безопасность -> Имена входа -> Правой кнопкой по user_name -> Свойства -> База данных по умолчанию -> test_db
В этом случае ваш вариант будет работать без изменений.
UPD
4. Указать БД в панели "Редактор SQL"

Как сверстать блок c такими рамками?


Есть идеи как сверстать фиксированный блок с такими рамками? Картинка сплошная, сделана бекграундом. Пробовал таким образом, но при добавлении текста все ломается.
.block { display: inline-block; height: 318px; } .block-1 { box-sizing: border-box; width: 739px; padding: 35px; padding-right: 0; border: 3px solid #fff; border-right: none; } .block-2 { width: 198px; margin-left: -4px; border-bottom: 3px solid #fff; } .block-3 { width: 198px; margin-left: -3px; border: 3px solid #fff; border-left: none; }



Ответ

Если заведомо известно, что человек будет "под рамкой" только снизу или сверху, то сымитировать нижнюю или верхнюю рамку можно псевдоэлементами :before или :after соответственно:
html, body { padding: 0px; margin: 0px; background: lightblue; } * { box-sizing: border-box; } .block { position: relative; max-width: 580px; margin: 50px auto; border: #fff solid 2px; border-bottom: none; padding: 40px 270px 40px 20px; } .block:after { display: block; content: ''; width: 100%; height: 2px; background: #fff; position: absolute; z-index: 2; left: 0px; bottom: 0px; } .block-text { color: #fff; font-size: 14px; line-height: 20px; } .block-img { position: absolute; z-index: 1; right: 10px; top: -40px; width: 250px; } .block-img img { width: 100%; }

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Дизассемблирование кода в codeblocks

Здравствуйте! Подскажите, пожалуйста, как дизассемблировать код в codeblocks?


Ответ

Дебагер (gdb 8.0) из текущей поставки mingw-w64 (который i686-7.1.0-release-posix-dwarf-rt_v5-rev2.7z) при отладке С++ кода у меня зависает (при отладке С такого не наблюдается), возможно и у вас такая же проблема и поэтому окно Disassembly пустое.
Попробуйте поставить рядом более старую версию mingw-w64 и указать в настройках CodeBlocks чтобы он использовал gdb из той сборки.
Зайдите в настройки дебагера (Меню - Settings - Debugger), создайте новую конфигурацию (GDB/CDB Debugger - Create config) и укажите путь к нужному gdb.exe:

Так же, CodeBlocks может выводить ассемблерный код в двух форматах AT&T и Intel. Это настраивается тут же, в свойствах дебагера - Choose diassembly flavor (GDB only)
После того, как вы добавили новый дебагер, вы можете переключаться между ними через Меню - Debug - Active debuggers

Инструкция о том, как увидеть ассемблерный код:
В качестве Build target выбрать Debug: Меню - Build - Select target - Debug Сделать Rebuild проекта: Меню - Build - Rebuild (Ctrl+F11) Если проект собрался успешно, поставить брекпоинт на строке кода и запустить отладку: Меню - Debug - Start /Continue (F8) После этого запустится дебагер и остановится на вашем брекпоинте. В этот момент и можно посмотреть дизассемблированный код: Меню - Debug - Debugging windows - Disassembly

При этом, в логе на вкладке Debugger, будут примерно вот такие строчки:
Starting debugger: C:\dev\mingw-w64_5.3.0\bin\gdb.exe -nx -fullname -quiet -args B:/test/bin/Debug/test.exe done Registered new type: wxString Registered new type: STL String Registered new type: STL Vector Setting breakpoints Debugger name and version: GNU gdb (GDB) 7.10.1 Child process PID: 4044 At B:\test\main.cpp:7

punycode. передача пременной из bash в python в функцию encode('idna')

существует файл py1 c следующим содержанием:
python -c "x=u'''$1'''; print x.encode('idna')"
буква u, в начале значения для переменной - это попытка привести ввод в bash
./py1 подпись.рф
к следующему виду в python:
x=u"подпись.рф"
так вот, при вызове скрипта получаем следующий вывод:
~$ ./py1 а xn--nba1k ~$ ./py1 апо xn--34-eea4dwnbb5725d
но:
~$ ./py1 ф Traceback (most recent call last): File "", line 1, in File "/usr/lib/python2.7/encodings/idna.py", line 164, in encode result.append(ToASCII(label)) File "/usr/lib/python2.7/encodings/idna.py", line 76, in ToASCII label = nameprep(label) File "/usr/lib/python2.7/encodings/idna.py", line 38, in nameprep raise UnicodeError("Invalid character %r" % c) UnicodeError: Invalid character u'\x84'
ошибка по-видимому в данном месте
u'''$1'''
и возможно логичнее было бы воспользоваться sys.argv[] в python, однако я никак не возьму в толк, как верно вставить полученную переменную в python из sys.agr в другую, с параметром u перед строкой, пробовал следующий подход:
создается файл wpq1.py с нижеизложенным:
# -*- coding: UTF-8 -*- import sys
x= unicode(sys.argv[1]) print x
затем вызывается в shell:
~$ python wpy1.py фырфырфыр Traceback (most recent call last): File "wpy1.py", line 5, in x= unicode(sys.argv[1]) UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 0: ordinal not in range(128)


Ответ

В Питоне 3 sys.argv уже как Unicode пришёл бы:
$ python3 -c 'import sys; print(sys.argv[1].encode("idna").decode())' пример.рф xn--e1afmkfd.xn--p1ai
В Питоне 2, самостоятельно аргументы командной строки из байт в текст декодировать необходимо. Для этого нужно выбрать кодировку. Для системных строк: argv, переменных окружения, путей можно sys.getfilesystemencoding() кодировку использовать (с оговорками):
$ python2 -c 'import sys; print sys.argv[1].decode(sys.getfilesystemencoding()).encode("idna")' пример.рф xn--e1afmkfd.xn--p1ai
На Linux sys.getfilesystemencoding() от локали зависит. Подробнее Как работать с путями c русскими символами?
В общем случае, системные строки это почти произвольный набор байт, который не всегда как текст можно интерпретировать, поэтому существует surrogateescape обработчик ошибок, который также может активироваться на Python 3, если локаль не настроена (или неверно настроена):
$ LC_ALL=C python3 -c 'import sys; print(sys.argv[1].encode("idna").decode())' пример.рф Traceback (most recent call last): File "/usr/lib/python3.5/encodings/idna.py", line 181, in encode result.extend(ToASCII(label)) File "/usr/lib/python3.5/encodings/idna.py", line 76, in ToASCII label = nameprep(label) File "/usr/lib/python3.5/encodings/idna.py", line 38, in nameprep raise UnicodeError("Invalid character %r" % c) UnicodeError: Invalid character '\udcd0'
Локаль по умолчанию (поломанные или вообще отсутствующие настройки) подразумевает ascii кодировку (С, POSIX). Поэтому при запуске init-скриптов (сервисы), при заходе по ssh, в cron-скриптах, убедитесь что локаль c нужной кодировкой определена, чтобы не-ascii содержимое такое как IDN обрабатывать. Иначе ошибку получите:
$ LC_ALL=C python2 -c 'import sys; print sys.argv[1].decode(sys.getfilesystemencoding()).encode("idna")' пример.рф Traceback (most recent call last): File "", line 1, in UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)
Если вы решите жёстко прописать кодировку такую как utf-8, то будьте уверены на 100%, что имена доменов у вас всегда всегда в этой кодировке генерируются в окружении, где вы запускаете ваш Питон-скрипт. Иначе или UnicodeDecodeError или хуже кракозябры получите, что приведёт к генерации неверного punycode (что вы можете не сразу заметить, что удорожает исправление ошибки).

Python 3.6 - парсинг файла и заполнение массива

Добрый день! Пишу 2D игру на Python 3.6 и возникла проблема создания массива. Python я начал изучать совсем недавно. Смысл такой - функция должна парсить файл карты и заполнять массив. Структура карты простая, в зависимости от символа другая функция загружает спрайт, например '=' - это кирпичная стена, но все это должно считываться из массива, который я пока не понял, как делать. Пример файла карты:
LevelsCount:2 LevelName:Name LevelNum:1 LevelType:Green { ==d===================== =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0001111122211111000000= =0000000000000000000000= ======================== }
Уровень из файла карты должен считываться в трехмерный (?) массив от "{" до "}", причем выборочно, если укажу '1' в параметр функции, то считываться только LevelNum:1. Каждая строка является новым элементом массива и каждый символ является элементом массива, чтобы при доступе получить, к примеру:
==d=====================
blocks[0][0] - '=' или blocks[0][2] - 'd', где [0] это номер строки, а [2] - номер символа в строке. Вот функция, которую я не могу написать правильно:
def parse_levelpack(chapt, lvl): lvl_file = open('pack/levels/Chapter' + str(chapt) + '.mapf', 'r') y_block = -1 x_block = -1 global levelCount line = lvl_file.readline() while line: line = line.replace('
', '') line = lvl_file.readline() if line.find('{') > -1: y_block = y_block + 1 x_block = -1 blocks_array[y_block].append([]) lvl_file.readline() if not line == '}': lvl_file.readline() x_block = x_block + 1 blocks_array[x_block].append([]) blocks_array[y_block][x_block].append(line[x_block]) lvl_file.close()
chapt - часть, добавляется к имени файла, lvl - чтобы из файла карты выбрать нужный уровень, например, LevelNum:1.


Ответ

Парсер простой, поэтому думаю автор сам его допилит, а я покажу пример парсера локаций:
def fill_blocks(text_or_list): blocks = []
if type(text_or_list) == str: line_list = text_or_list.splitlines() else: line_list = text_or_list
for line in line_list: line = line.strip() if not line: continue
row = [x for x in line] blocks.append(row)
return blocks
def get_text_level_blocks(text): text_level_blocks = []
start_block = False blocks_text = None
for line in text.splitlines(): line = line.strip() if not line: continue
if line == '{': start_block = True blocks_text = [] continue
elif line == '}': start_block = False text_level_blocks.append(blocks_text) continue
# Если не кирпич elif not line.startswith('='): continue
# Дальше ищем символ стартового блока if not start_block: continue
blocks_text.append(line)
return text_level_blocks
if __name__ == '__main__': text = """\ ==d===================== =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0000000000000000000000========= =000000000000000000000000000000= =0001111122211111000000========= =0000000000000000000000= ======================== """ blocks = fill_blocks(text) print(''.join(blocks[0])) print(blocks[0][0]) print()
many_level_text = """\ { ==d===================== =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0000000000000000000000========= =000000000000000000000000000000= =0001111122211111000000========= =0000000000000000000000= ======================== } ... { ==d===================== =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0001111122211111000000= =0000000000000000000000= ======================== } """
text_level_blocks = get_text_level_blocks(many_level_text) print(len(text_level_blocks))
level_block = text_level_blocks[0] blocks = fill_blocks(level_block) print(''.join(blocks[0])) print(blocks[0][0]) print()
all_levels_block = []
for level_block in text_level_blocks: blocks = fill_blocks(level_block) all_levels_block.append(blocks)
print(''.join(all_levels_block[0][4])) print(''.join(all_levels_block[1][4])) print(all_levels_block[0][0][2]) print(all_levels_block[1][0][2])
Консоль:
==d===================== =
2 ==d===================== =
=0000000000000000000000========= =0000000000000000000000= d d

Способы пропорционального масштабирования блоков

Есть блок, растянутый на всю ширину экрана, имеющий в качестве фона художественное изображение. При масштабировании экрана изображение не должно обрезаться и (непропорционально) сжиматься, то есть, насколько могу судить, высота блока должна подстраиваться под его ширину пропорционально размерам фонового изображения.
Вижу два варианта реализации:
Вложить фоновое изображение в блок посредством тега так, чтобы изображение само растягивало блок по высоте. Пропорционально менять высоту блока средствами JavaScript
Способа достичь желаемого при помощи css я не знаю. Хотелось бы узнать у профессионалов, как это принято (и правильно) делать, возможно, найдутся и другие способы, более приемлемые.


Ответ

Самый известный трюк - задавать пропорции с помощью height:0 и padding-bottom, так называемый padding-bottom hack
Значение для padding-bottom расчитывается по формуле:
высота изображения * 100 / ширина изображения
или
высота изображения / ширина изображения * 100

В данном снипете изображение имеет размеры 1280х720 пикселей, следовательно:
720 * 100 / 1280 = 56.25
.block { width: 100%; height: 0px; padding-bottom: 56.25%; background: url(http://files.all-free-download.com//downloadfiles/wallpapers/1280_720/heihachi_mishima_tekken_7_4k_17496.jpg) no-repeat center; background-size: cover; }


Как отключить сворачивание кода в Android studio?

Не могу отключить сворачивание кода в студии. Нашел только хот-кей. Но каждый раз нажимать надоедает. Отключение "closures" не помогает.


Ответ

File -> Settings.. -> Editor -> General -> Code Folding
Галочки в секции Collapse by Default указывают, какие части кода сворачивать по умолчанию.

Почему только статические методы?

Да, в C# очень обширная библиотека. Но почему то многие методы только статические. А хотелось бы ООП. А так, это же функциональщина получается. Взать тот же метод ForEach для массивов. Не применяется он к экземпляру класса. Пробовал сделать такую обёртку:
class Arr:Array { public void forEach(Action act) {Array.ForEach(this,act);}
}
Выдаётся ошибка, что от System.Array нельзя наследоваться. Может как то можно прилепить к массиву такой интерфейс с минимумом кода?


Ответ

Напишите метод расширения:
static class ArrayExt { public static void ForEach(this T[] source, Action action) { Array.ForEach(source, action); } }
Использовать можно, например, так:
int[] arr = { 1, 2, 3, 10 }; arr.ForEach(Console.WriteLine);

Статические переменные и методы класса

Как в современном (c++11 и более позднем) объявлять статические переменные в классе и можно ли вообще это делать?
#include #include
using namespace std;
int main() { class Class { static const short unsigned id = 1; static const string name = "Заголовок 1";
public: static short unsigned getId() { return id; }
static string getName() { return name; } };
cout<Я уже понял, что инициализировать статические переменные класса можно только либо из вне, или только если это константы, но не получается вообще никак.
g++ -Wall -march=native -msse3 -O3 -fomit-frame-pointer -pipe -o "oop" "oop.cpp" (в каталоге: /home/ilya/Downloads/Qt) oop.cpp: В функции «int main()»: oop.cpp:10:36: ошибка: локальный класс «class main()::Class» не должен иметь статический элемент данных «const short unsigned int main()::Class::id» [-fpermissive] static const short unsigned id = 1; ^ oop.cpp:11:30: ошибка: локальный класс «class main()::Class» не должен иметь статический элемент данных «const string main()::Class::name» [-fpermissive] static const string name = "Заголовок 1"; ^~~~~~~~~~~~~~~~~~~~~~ oop.cpp:11:23: ошибка: инициализация внутри класса статического элемента данных «const string main()::Class::name» нелитерального типа static const string name = "Заголовок 1"; ^~~~ oop.cpp:11:30: ошибка: вызов non-constexpr функции «std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [с _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator]» static const string name = "Заголовок 1"; ^~~~~~~~~~~~~~~~~~~~~~ Сборка завершилась с ошибкой.
И если определять из вне.
#include #include
using namespace std;
int main() { class Class { public: static short unsigned id; static string name; };
Class::id = 1; Class::name = "Заголовок 1"; cout<То всё равно не получается.
g++ -Wall -march=native -msse3 -O3 -fomit-frame-pointer -pipe -o "oop" "oop.cpp" (в каталоге: /home/ilya/Downloads/Qt) oop.cpp: В функции «int main()»: oop.cpp:11:25: ошибка: локальный класс «class main()::Class» не должен иметь статический элемент данных «short unsigned int main()::Class::id» [-fpermissive] static short unsigned id; ^~ oop.cpp:12:17: ошибка: локальный класс «class main()::Class» не должен иметь статический элемент данных «std::__cxx11::string main()::Class::name» [-fpermissive] static string name; ^~~~ Сборка завершилась с ошибкой.
Почему так происходит и что я делаю не так?


Ответ

Обратите внимание на ошибку. Там упоминается, что класс локальный.
#include #include
class Class { public: static const int id; // можно инициализировать тут static const std::string name; // нельзя инициализировать тут };
const int Class::id{111}; const std::string Class::name = "rectangle";
int main() { std::cout << Class::id << ' ' << Class::name << std::endl; return 0; }
Можно убрать константность, инициализация от этого не пострадает
#include #include
class Class { public: static int id; static std::string name; };
int Class::id{111}; std::string Class::name = "rectangle";
int main() { Class c; std::cout << c.id << ' ' << c.name << std::endl; return 0; }
Во втором примере можно обращаться по имени класса и далее через ::, я просто привел для примера через экземпляр и Также рекомендую обратить внимание на фигурную инициализацию, через {}, как сделал для id, она имеет ряд преимуществ, но иногда стоит быть осторожнее, потому что из нее получается объект std::initializer_list. Что касается инициализации внутри класса, то это возможно, если мы имеем статическую константу и интегральный тип:
class Curious { static const int c1 = 7; // правильно, но помните об определении static int c2 = 11; // ошибка: не константа const int c3 = 13; // ошибка: не статическая константа static const int c4 = f(17); // ошибка: инициализатор не константа static const float c5 = 7.0; // ошибка: не интегральный тип // ... };
Если (и только если) Вы используете инициализированный член таким образом, что требуется хранить его в памяти, как объект, член должен быть где-нибудь (один раз) определен. Инициализатор не может повторяться:
const int Curious::c1; // это определение, но не повторяйте здесь инициализатор const int *p = &Curious::c1; // правильно: Curious::c1 был определен

Как посмотреть по http наличие файла? (node js)

Как на ноде проверить наличие файла в дерриктории http? Мне не нужно его скачивать, просматривать, а просто знать - есть он или нет. По сути мне нужно отправить http запрос например на урл http://example.org/file.txt и получить ответ, распарсить и если 404 не наблюдаю то гуд иначе не гуд...


Ответ

Для определения наличия ресурса можно использовать метод HEAD. В ответ на HEAD запрос не будет возвращаться содержимое файла. При этом потребуется проверить код ответа: 200 - ресурс есть. Вы можете использовать, например, модуль request, который дочтаточно прост и содержит функцию head:
const request = require("request");
request.head("http://www.cfcl.com/vlb/Cuute/f/a-few-bricks.txt").on("response", res => { global.console.log(res.statusCode); });
или использовать модуль http самой ноды и функцию request
const http = require("http");
const req = http.request( { hostname: "www.cfcl.com", path: "/vlb/Cuute/f/a-few-bricks.txt", method: "HEAD", }, res => { global.console.log(res.statusCode); }, );
req.end();

Динамическое создание конструктора

В Java программе необходимо создать объект, но заранее не известно сколько и какие поля будут участвовать в конструкторе. Есть ли возможность во время выполнения добавлять к классу конструктор с необходимым набором параметров?


Ответ

Есть такой способ хакинга (заранее предупреждаю, что это антипаттерн):
Задаемся некой структурой данных описывающих поведение гипотетического конструктора (в реалии конечно же класс с заданным конструктором) - нечто типа псевдоязыка - вполне сойдет какой-нибудь xml/json Парсим псевдоязык и генерируем на лету исходник класса Через ToolProvider вызываем в рантайме компилятор Javа Далее через ClassLoader загружаем объектник класса Далее уже все как обычно: у нас есть ссылка на класс, вызываем через рефлексию его конструктор.
Еще раз - так не рекомендуется делать, но иногда так делается. Сам лично когда то делал такую поделушку.

Вызвано исключение по адресу: нарушение прав доступа при чтении по адресу

void fillMassL(float **massL, int size) { for (size_t j = 0; j < size; j++) { for (size_t i = 0; i < size; i++) { if (i == j) massL[j][i] = 1; else massL[j][i] = 0; } } }
Компилятор показывает ошибку где-то тут, но вообще не могу понять что не так.
if (i == j) massL[j][i] = 1; else massL[j][i] = 0;
Cообщение компилятора: Вызвано исключение по адресу 0x00007FF6B49826F5 в LR1.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xFFFFFFFFFFFFFFFF., произошло
Вызов функции:
fillMassL(ptr_massL, *ptr_size);
Создание ptr_massL:
int *ptr_size = new int; *ptr_size = 5; float **ptr_massL = new float*[*ptr_size];


Ответ

Maccив ptr_massL создан некорректно. Должны быть 2 этапа:
Выделяется память под сам массив указателей на float В цикле выделяется память под каждый его элемент.
float **ptr_massL = new float*[*ptr_size]; for(int i = 0; i < *ptr_size; ++i) ptr_massL[i] = new float[*ptr_size];
Вот тогда все будет ок.

Скачивание картинки

Есть картинки, после клика на картинку выполняется код:
var isAdmin = confirm("Скачать");
Как сделать чтобы, когда confirm возвращает true начиналось скачивание картинки на которую нажали?


Ответ

Чтобы позволить пользователю загружать изображение или другой файл вы можете использовать HTML5 атрибут download
https://stackoverflow.com/questions/7951326/save-image-to-users-disk-using-javascript/37521282#37521282
Можно эмулировать такую загрузку. function saveUrlAsFile(url, fileName) { var link = document.createElement("a"); link.setAttribute("href", url); link.setAttribute("download", fileName); link.click(); } $('img').on('click',function(e){ var isAdmin = confirm("Скачать?"); if(isAdmin){ saveUrlAsFile($(e.target).attr('src'), 'image.jpg'); } });
IE не поддерживается

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

У меня есть список фотографий, который я отображаю в ListView с помощью адаптера.
Сейчас я отображаю фото таким образом:
PhotoAdapter.ViewHolder viewHolder; if (view == null) { view = inflater.inflate(R.layout.list_view_photo_item, viewGroup, false);
viewHolder = new PhotoAdapter.ViewHolder(view); view.setTag(viewHolder); } else { viewHolder = (PhotoAdapter.ViewHolder) view.getTag(); }
picasso.load(photo.getImageUrl()) .placeholder(R.drawable.bg_small_11) .into(viewHolder.image);
Это обычное отображение. А у меня стоит задача отобразить фото по указанным координатам (левая верхняя, правая верхняя, левая нижняя и правая нижняя точка). То есть я не хочу отображать всё фото, а только этот кусок фото, который пользователь раньше выбрал как превью, и я хочу отображать именно его. Сервер мне возвращает полностью всё фото + координаты (в PX) этого превью. Кто, что может посоветовать?


Ответ

Метод transform и интерфейс Transformation позволяют изменить изображение как душе угодно:
picasso.load(photo.getImageUrl()) .placeholder(R.drawable.bg_small_11) .transform(new Transformation {
@Override public Bitmap transform(Bitmap source) { Bitmap result = Bitmap.createBitmap(source, x, y, width, height); if (result != source) source.recycle(); return result; }
@Override public String key() { return "crop()"; } }) .into(viewHolder.image);

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

Дан массив из n элементов, упорядоченный в порядке неубывания, найти первое и последнее вхождение числа в массив. Так как массив отсортирован, напрашивается использование бинарного поиска. Я использовал его для нахождения первого вохождения, но не знаю как его изменить, чтобы искать последнее вхождение.


Ответ

Просто использовать разное поведение при решении, в какую сторону двигаться, если нашли значение, равное искомому. Пример на Java:
int binarySearch(int[] a, int fromIndex, int toIndex, int key, boolean last) { int low = fromIndex; int high = toIndex - 1;
while (low <= high) { int mid = (low + high) >>> 1; int midVal = a[mid];
if (midVal < key || (last && midVal == key)) low = mid + 1; else if (midVal > key || (!last && midVal == key)) high = mid - 1; } return last ? high : low; }

Где происходит шифрование данных, и где находится ключ tls/ssl?

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


Ответ

Шифрование происходит с обеих сторон. Ведь если шифровать будет только одна сторона (например только сервер), значит трафик от другой стороны (от клиента) будет не зашифрован. Его можно будет подслушать или даже изменить. Формально никто не передает никому ключ. В протоколе TLS клиент и сервер должны сгенерировать общий секрет (shared secret), набор из 48 байт. Потом клиент и сервер на основании общего секрета вычисляют ключи: ключ шифрования клиента и ключ шифрования сервера. Процедура вычисления ключей из общего секрета стандартная, и задана в описании протокола TLS. Сервер и клиент знают 2 ключа шифрования, одним шифруют, вторым дешифруют. А теперь самое интересное - как клиент и сервер вычисляют общий секрет. Это зависит от выбранного набора шифров:
TLS_RSA_WITH_: В данном случае клиент сам создает общий секрет генерируя 48 случайных байт. Затем он шифрует их при помощи публичного RSA ключа, который находится в сертификате сервера. Сервер получает зашифрованные данные, и расшифровывает их при помощи приватного RSA ключа. Данная схема используется редко. TLS_DHE_RSA_/TLS_ECDHE_RSA_/TLS_ECDHE_ECDSA_: Здесь используется криптографическая схема Диффи-Хеллмана (DHE) или ее версия на эллиптических кривих (ECDHE). Суть схемы такая: сервер и клиент генерируют случайные большие числа (приватные ключи), вычисляют на их основе другие числа (публичные ключи), и пересылают друг другу. Имея свой приватный ключ и публичный ключ другой стороны, они вычисляют общий секрет. Третья сторона, которая прослушивает канал, видит только 2 публичных ключа, и она не может вычислить общий секрет. После этого все данные, которыми обменивались клиент и сервер для получение этого ключа подписываются сертификатом сервера (RSA или ECDSA подписи). Если клиент доверяет сертификату сервера, он проверяет эту подпись, и если она правильная, начинается уже обмен данными. Это наиболее часто используемая схема. Есть еще несколько схем, но они используются очень редко или не используются вообще.
Про перехват. Как я выше описал, перехватывать сообщения здесь бесполезно, так как в первом случае его может расшифровать только сервер, а во втором используется хитрая криптографическая схема. Алгоритмы шифрования знает и сервер, и клиент. Ведь если клиент не знает, какой алгоритм шифрования, как он будет шифровать данные для отправки? В современной криптографии никто не использует закрытые алгоритмы. Открытые алгоритмы постоянно изучаются лучшими криптографами мира, ищутся уязвимости, и предлагаются решения для их обхода.
В TLS мы условно можем сказать, что алгоритмы меняются, так как каждый раз генерируются другие ключи шифрования. А потом, если вы хотите использовать закрытый алгоритм, например для просмотра веб-страницы, каким образом этот алгоритм может быть закрытый, если ваш компьютер/устройство производит шифрование/дешифрование?
Я упустил/упростил некоторые детали, что бы описать только основные идеи.

Безопасное сравнение указателей

Безопасен ли данный код.
#include
int main(int argc, char* argv[] ) { constexpr auto SIZE = 3; int* a1 = new int[3];
a1[0] = 1; a1[1] = 2; a1[2] = 3;
int* first = a1; int* last = a1 + SIZE;
for ( ; first != last; first++) std::cout << *first;
return 0; }
В конце последней итерации first вне диапазона, можно ли так сравнивать указатели. Что будет если first будет равен максимальному size_t.


Ответ

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

Вопрос по терминологии Java

У Шилдта заметил такое понятие как "область действия". Судя по тексту это то же самое что и "область видимости". Есть ли разница между этими терминами, или все это происки надмозгов?
Во многих языках программирования поддерживаются две общие категории областей действия: глобальная и локальная.
Шилдт Герберт - Java: руководство для начинающих


Ответ

Герберт Шилдт. Java 8: руководство для начинающих. 6-е издание (стр. 69, раздел "Область действия и время жизни переменных"):
Как пояснялось в главе l, блок начинается с открывающей фигурной скобки и оканчивается закрывающей фигурной скобкой. Блок определяет область действия (видимости) переменных. Начиная новый блок, вы всякий раз создаете новую область действия.
Herbert Schildt. Java. The complete reference. Ninth edition. (стр. 45, раздел "The Scope and Lifetime of Variables"):
As explained in Chapter 2, a block is begun with an opening curly brace and ended by a closing curly brace. A block defines a scope. Thus, each time you start a new block, you are creating a new scope.
То, что в оригинале описывается одним словом scope, перевели двумя разными словосочетаниями область видимости и область действия. В общем понятно, что это одно и то же.