Страницы

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

воскресенье, 26 января 2020 г.

подделка сессии

#php #взлом


Допустим с помощью php создаю сессию:

$_SESSION['user_id'] = 22;


Браузер я так понимаю, создает cookie с id юзера в зашифрованном виде (скажем с помощью
md5). То есть если генерировать с помощью md5 user_id другой (17 к примеру) и заменить
cookie, то получается можно получить доступ к юзеру с id 17?
Или я что-то не понимаю?
    


Ответы

Ответ 1



У каждой PHP сессии уникальный код который нельзя так просто подобрать, а все данные сессии хранятся только на сервере этот "уникальный код" который устанавливается в cookie т.е работает так Юзер заходит на сайт (при запросе на скачивание html в HTTP заголовках возвращается запрос на установку в cookie с названием PHPSESSION уникального кода который не зависит от $_SESSION['user_id'] = 22;) Потом браузер просто с этим ключом обращается к серверу Проще говоря можно представить что $_SESSION это файл сессии, user_id ячейка в этом файле, а 22 это значение ячейки user_id P.s данные сессии не как нельзя получить на стороне пользователя (если их только самому не отдать ему к примеру выводом через echo $_SESSION['user_id'];)

Ответ 2



У сервера есть ящик. В ящике лежит user_id = 22. Сервер на ящик прибивает табличку с какой-нибудь аброкадаброй и хранит у себя все время сам ящик, никому не дает его. Затем сервер говорит браузеру: "Запиши, браузер, аброкадабру с таблички этого ящика. В следующий раз, когда придешь снова, сообщи мне ее и я загляну в ящик с этой табличкой, чтобы узнать тебя".

Ответ 3



итак: Допустим, вы раздаете сайт по протоколу http. можете считать, что всех ваших пользователей уже взломали, админку тоже увели. этот случай не рассматриваем. Допустим, вы раздаете сайт по протоколу https Вы делаете куку, выдаете пользователю. пользователь заходит на сайт, и оставляет где-нибудь коммент, содержащий js-код. поскольку вы не разбираетесь в куках, то и в фильтрации js вы тоже не разбираетесь. В простейшем случае, JS-код выдаст в браузер что-нибудь типа . У вас XSS-уязвимость. Каждый посетитель страницы с таким кодом отправит свою куку на сервер атакующего. Условно говоря, кука (в данном случае, айдишка в куке) прокидывается к атакующему. Если кука прокинулась к атакущему, простейший скрипт позволит ему при получении куки автоматически сделать какие-нибудь нехорошие действия, например, зайти под вами в админку, перезаписать какой-нибудь файл, сохранить его, вы даже и не заметите, что произошло. Просто какой-то сервер в интернете за 1-2 секунды авторизовался под вами и сделал все что нужно. Изменил плагин вордпресса, например. А автор заразы в это время спит себе спокойно. Скрипт работает. А он спит. А у тебя сифилис на сайте. И какой-нибудь вредоносный код, заражающий пользователей. В итоге - сервер заражен, пользователи заражены, "и мы в аду и ты горишь, сынок." Чтобы кука была недоступна для js-кода в браузере, придумали специальный флаг HttpOnly - почитайте здесь Это одна из причин, почему некоторые сайты не позволяют заходить одновременно с двух ip-адресов. Для идентификации пользователя используется пара id+ip. И именно поэтому, например, какой-нибудь альфа-банк разлогинивает вас автоматически через, кажется, 10-15 минут неактивности. Пришел к тебе друг, а ты вышел собаку прогулять, а комп забыл залочить. Находясь в одной и той же подсети, например, можно стащить куку, и пара cookie/ip с другого компьютера в той же подсети вполне себе сработает без всякого ip spoofing. (тут я не в курсе, насколько защита от ip spoofing продвинулась за последние несколько лет) p.s. поскольку я не специалист по безопасности, а если бы и был, врядли смог бы выдать полное руководство в ответе, рекомендую вам погуглить и почитать про такие вещи самому. p.p.s https-сертификат бесплатно нынче модно получать у https://letsencrypt.org p.p.s. если вы решите создавать куки самостоятельно, при помощи md5 от id пользователя, то не решайте так. Какой-нибудь милый человек посмотрит сколько у вас примерно пользователей, после этого будет время от времени (в зависимости от количества пользователей) делать запросы с подходящим md5. Если вы еще приделаете список пользователей онлайн - будет еще легче. Про соль вы забудете, про перец забудете и в итоге сессия вашего юзера будет md5(1), md5(2), md5(n)... Можно просто сделать md5(1) = авторизован = творю что хочу. Не балуйтесь с крипто, не прочитав про него. Пользуйтесь встроенными механизмами генерации куки от php/почитайте про шифрование и хэширование. p.p.p.s еще бывает очень смешно, когда session_id передают через get-запрос, т.е. session_id появляется в адресной строке браузера. Если посетителя вашего сайта попросят прислать ссылку на материал вашего сайта, или он сам выложит ее куда-нибудь, то произойдет авто-логин

Как создать полу дугу [закрыт]

#css #css3


        
             
                
                    
                        
                            Закрыт. Данный вопрос необходимо конкретизировать. Ответы
на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он был сосредоточен только на одной проблеме, отредактировав его.
                        
                        Закрыт 3 года назад.
                                                                                
           
                
        
Как создать полу дугу, создаю дугу с помощью border-bottom:1px solid #000; это полная
дуга, а как сделать ее половинку(или больше половины), идея такая 30% этой дуги желтая,
остальная зеленая.
    


Ответы

Ответ 1



.b-circle{ margin: 15px auto; width: 200px; height: 200px; background: #ccc; border-radius: 50%; overflow: hidden; position: relative; } .b-circle:before{ content: ''; position: absolute; top: 10px; left: 10px; width: calc(100% - 20px); height: calc(100% - 20px); background: #fff; z-index: 1; border-radius: 50%; } .b-circle > span{ position: absolute; } .b-circle > span:nth-of-type(1){ top: 0; height: 50%; width: 100%; /*background: #FD6347;*/ } .b-circle > span:nth-of-type(1):before{ content: ''; position: absolute; top: 0; left: 0; width: 30%; height: 100%; background: yellow; } .b-circle > span:nth-of-type(1):after{ content: ''; position: absolute; top: 0; left: 30%; width: 70%; height: 100%; background: green; } .b-circle > span:nth-of-type(2){ top: 50%; height: 50%; width: 100%; background: #008080; }


Ответ 2



Как вариант #semiarc { position: relative; width: 200px; height: 200px; border: 10px solid #ff8040; border-radius: 50%; overflow: visible; box-sizing: border-box; } #semiarc > div { position: absolute; width: inherit; height: inherit; border-radius: inherit; box-sizing: inherit; margin: -10px auto auto -10px; border: 10px solid #060; clip: rect(0, 200px, 100px, 0); }


Ответ 3



Вот так ps: svg это мощь это малая часть что можно делать на нём

Флажок на html/css

#html #css


Можно ли как-нибудь воссоздать такой флажок на css/html?



p.s. - интересует только флажок,без жёлтой полосы.
    


Ответы

Ответ 1



Например так: body { background-color: white; } .flag { background-color: red; width: 100px; height: 200px; position: relative; } .flag::before { content: ''; display: inline-block; position: absolute; width: 0; height: 0; bottom: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 100px solid white; }


Ответ 2



еще как вариант .flag { background-color: red; width: 100px; height: 150px; position: relative; -webkit-clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 70%, 0 100%); clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 70%, 0 100%); }


Ответ 3



Ну и я свои пять копеек вставлю

Ответ 4



Создаешь блок и добавляешь стили .flag { background-color: #000; position: relative; width: 40px; height: 80px; } .flag:before { content: ''; display: block; position: absolute; top: 100%; border-left: 20px solid #000; border-right: 20px solid #000; border-bottom: 20px solid transparent; }


Ответ 5



Флажок можно разбить на 3 фигуры: 1 прямоуглольник и 2 треугильника. Прямоугольник можно сделать простым дивом, с красным бэкгрундом. Сдесь описано как на html+css создавать треугольники.

Intellij Idea потеряла jdk после его обновления

#intellij_idea #java


Раньше было установлено jdk 1.7. Затем, я установил jdk 1.8, а старый удалил. После
чего пропали классы оболочки и запуск происходит с ошибкой:


  Error:Cannot run program "C:\Program Files\Java\jdk1.7.0_79\bin\java" (in directory
"C:\Users\ssaan.IdeaIC2016.2\system\compile-server"): CreateProcess error=2, Не удается
найти указанный файл


Где поменять путь на jdk 1.8??? 
    


Ответы

Ответ 1



Shift+Ctrl+Alt+S, а там во вкладке Project SDK выбирайте новую версию. Обычно лежит в папке C:\Program Files\Java\..

Ответ 2



Файл -> Настройки проекта там укажешь какую версию. по умолчанию автоматом подтянет, а если нет - то создай через new

Ответ 3



File -> Project Structure -> Project -> Project SDK -> new / edit -> выставляешь путь до новой джавы

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

#любой_язык #code_style


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


Ответы

Ответ 1



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

Ответ 2



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

Ответ 3



Хорошие комментарии именно в коде (а не перед функциями и т.п.) должны пояснять зачем этот кусок нужен для решения задачи. Вполне вероятно, что для понимания этого "зачем", потребуется описать состояние исходных данных и что получается после выполнения комментируемого кода. А как именно это реализуется, желательно рассказывать самим кодом.

Почему консоль пикает? [закрыт]

#c_sharp #консоль #текст


        
             
                
                    
                        
                            Закрыт. Этот вопрос необходимо уточнить или дополнить
подробностями. Ответы на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Добавьте больше подробностей
и уточните проблему, отредактировав это сообщение.
                        
                        Закрыт 2 года назад.
                                                                                
           
                
        
static void Main(string[] args)
{
    byte[] data = new byte[] { 8, 8, 3, 8, 5, 6, 7, 8 };
    Console.WriteLine(Encoding.UTF8.GetString(data));
    Console.ReadLine();
}


С чего бы это?
    


Ответы

Ответ 1



И правда, с чего бы ей пикать при выводе символа с кодом 7 - BEL (Bell, он же звонок)?

Управление доступом

#cpp #ооп #классы #инкапсуляция


Как еще можно обойти защищенность полей в ооп? кроме дружественных функций 
    


Ответы

Ответ 1



Если говорить действительно о "взломах защиты", т.е. о способах, которые не требуют кооперации со стороны "взламываемого" класса (т.е. не опираются на изначально заложенные в класс возможности, типа "друзей", методов, возвращающих указатели на члены и т.п.), то одна из малоизвестных "дыр", созданных в языке намеренно - это разрешение для явного инстанциирования шаблона игнорировать ограничения доступа. В следующем примере мы, не используя никаких "хаков", "друзей" или методов самого класса, обходим защиту доступа к private методу #include class Private { void private_func() { std::cout << "Pwned!" << std::endl; } }; using PTR = void (Private::*)(); PTR ptr; template struct Exploit { static inline struct D { D() { ::ptr = ptr; } } d; }; template struct Exploit<&Private::private_func>; int main() { (Private().*ptr)(); } Ключевой момент этой возможности - в разрешении (данном нам разделом 14.7.2/12 стандарта языка) делать template struct Exploit<&Private::private_func>; несмотря на то, что функция Private::private_func является private.

Ответ 2



В общем случае? Или в каких-то конкретных? Читерство типа #define private public считаем недостойным настоящего программиста? :) Копирование описания класса из заголовочного файла с добавлением в него, например, дружественной функции - тоже? Есть вариант с созданием своего класса с аналогичным размещением членов в памяти и reinterpret_cast указателя на один объект в указатель на свой - незаконно, UB, но... обычно вполне прокатывает :) Например, через указатель - если тот же друг создаст указатель на что-то закрытое и вернет его, типа class X { private: int y; friend int* z(X&x) { return &x.y; }; ... int * p = z(x); *p = 5; Или это не годится, хотя дружественная функция используется опосредованно? Вот вариант со специализацией шаблонной функции. Допустим, есть некий класс. class X { public: template void f(const T& t) { /* ... */ } private: int p; }; Специализируем эту функцию... namespace { struct Y{}; } template<> void X::f(const Y&) { p = 5; } и все. Ловкость рук и никакого мошенничества...

Заполнение матрицы квадратной матрицы с конца

#c_sharp


Помогите как заполнить матрицу 3х3 такими же числами в таком же порядке. Умею заполнять
двумерный массив, но вот такие правила заполнения не имею описывать. 

Картинка в качестве примера:



Вот так заполняю и вывожу обычно, как это можно исправить?

int[] number = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        int[,] matrix = new int[3, 3];
        int index = 0;
        for (int i = 0; i < matrix.GetLength(0); i++)
            for (int j = 0; j < matrix.GetLength(1); j++)
            {
                matrix[i, j] = number[index];  
                    index++;                                       
            }

        for (int i = 0; i < matrix.GetLength(0); i++)
            for (int j = 0; j < matrix.GetLength(1); j++)
                if (j == matrix.GetLength(1) - 1)
                    Console.Write(matrix[i, j].ToString() + "\r\n");
                else Console.Write( matrix[i, j].ToString() + "\t");

    


Ответы

Ответ 1



Например, так: const int max = 3; int[,] matrix = new int[max, max]; int curr = 1; for (int diff = 1 - max; diff <= max - 1; diff++) { for (int i = 0; i < max; i++) { int j = i - diff; if (j < 0 || j >= max) continue; matrix[i, j] = curr++; } } Проверяем: for (int i = 0; i < max; i++) { for (int j = 0; j < max; j++) Console.Write(matrix[i, j] + " "); Console.WriteLine(); } Результат: 4 2 1 7 5 3 9 8 6 Пояснение: У клеток каждой диагонали разность координат y и x постоянна. Минимальная разность для «самой верхней» диагонали, в ней лишь клетка (max - 1, 0), разность равна 1 - max. Минимальная разность для «самой нижней» диагонали, в которой клетка (0, max - 1) равна, разумеется, max - 1. Внешний цикл по этим самым диагоналям. Одна разность — одна диагональ. Затем, в каждой диагонали проводим цикл по x-координате (в коде обозначена как i). Она может быть от 0 до max - 1. Но например для первой диагонали не все x возможны, т. к. в ней только один элемент. Поэтому мы действуем так: вычисляем x, имея разность y - x == diff, вычисляем y (в коде j). Проверяем, чтобы y опадало в промежуток от 0 до max - 1. В каждую найденную клетку записываем следующее число. Текущее число хранится, понятно, в переменной curr, и увеличивается на единицу после каждой записи в матрицу.

Ответ 2



Как вариант var matr = new int[3,3]; var cnt = 0; for(var y=2; y>=-2; y--) for(var x=0; x<3; x++) if((y+x) >= 0 && (y+x)<3) matr[x, y+x] = ++cnt; проверка for (var i = 0; i < 3; i++) { for (var j = 0; j < 3; j++) Console.Write($"{matr[i, j]} "); Console.WriteLine(); } Вывод 4 2 1 7 5 3 9 8 6

Ответ 3



Наивные реализации разобрали до меня, что ж... Если присмотреться, то можно заметить некоторое сходство искомого порядка заполнения массива с поиском в ширину, воспользуемся этим и получим такое решение: class Program { static void Main(string[] args) => new Program().Run(); const int dim = 10; int[,] matrix = new int[dim, dim]; Queue<(int, int)> queue = new Queue<(int, int)>(); void Run() { Fill(); Print(); } void Fill() { int index = 0; queue.Enqueue((dim - 1, 0)); while (queue.Count > 0) { var (x, y) = queue.Dequeue(); matrix[x, y] = ++index; if (x > 0) EnqueueIfNotUsed(x - 1, y); if (y < dim - 1) EnqueueIfNotUsed(x, y + 1); } } void EnqueueIfNotUsed(int x, int y) { if (matrix[x, y] == 0 && !queue.Contains((x, y))) queue.Enqueue((x, y)); } void Print() { var width = (dim * dim).ToString().Length + 1; for (int y = 0; y < dim; y++) { for (int x = 0; x < dim; x++) Console.Write(matrix[x, y].ToString().PadLeft(width)); Console.WriteLine(); } Console.ReadKey(); } }

Ответ 4



Вот мой вариант. Он любопытен тем, что он реально заполняет змейкой и это особенно наглядно видно, если во входном массиве не хватает данных для полного заполнения квадрата ну и под отладкой: 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20 10 0 0 0 31 0 0 0 0 0 0 0 0 0 44 20 10 0 0 0 31 0 0 0 0 0 0 0 0 0 44 20 10 0 0 55 31 0 0 0 0 0 0 0 0 Сам код: void Main() { const int max = 4; int[] numbers = { 10, 20, 31, 44, 55, 66, 77, 88, 90, 91, 92, 93, 94, 95, 96, 97 }; var result = this.Putty(max, numbers); PrettyPrint(result, max); } // Define other methods and classes here public int[,] Putty(int size, int[] numbers) { int[,] matrix = new int[size, size]; int x = 0; int y = size - 1; int turnAbove = 0; int turnBelow = 0; var iter = numbers.GetEnumerator(); while (iter.MoveNext()) { matrix[x, y] = (int)iter.Current; PrettyPrint(matrix, size); x++; y++; if (x >= size && y >= size) { turnBelow++; y = 0; x = turnBelow; } else if (y >= size) { turnAbove++; x = 0; y = size - 1 - turnAbove; } else if (x >= size) { turnBelow++; y = 0; x = turnBelow; } } return matrix; } public void PrettyPrint(int[,] matrix, int max) { Console.WriteLine(); for (int i = 0; i < max; i++) { for (int j = 0; j < max; j++) Console.Write(matrix[i, j] + " "); Console.WriteLine(); } } Если у вас входные числа идут не по порядку - самое то алгоритм, O(n) Основа алгоритма - переход от текущей клетки x,y по диагонали через одновременное инкрементирование x и y. Далее нужно написать условия определения того, что мы выскочили за край массива. Я насчитал три варианта вылета: над диагональю, когда вылетели за вертиальную границу; под диагональю, когда вылетели за горизонтальную границу и на диагонали (вылетели одновременно за обе границы). Вероятно, алгоритм можно попробовать оптимизировать (сократить число вспомогательных переменных или веток условий), оставляю место для творчества. Так же я не стал учитывать вариант, когда у нас массив полностью заполнен, а входной IEnumerable ещё не кончился.

Ответ 5



А давайте просто вычислим значение по данным индексам. Над диагональю это просто: считаем элементы в предыдущих диагоналях (сумма арифметической прогрессии), и прибавляем номер в текущей диагонали. А чтобы не думать, что там под диагональю, воспользуемся симметричностью. Итого: static int GetValue(int i, int j, int max) { if (i <= j) { int d = (i - j) + max - 1; // номер диагонали int s = d * (d + 1) / 2; // сумма предыдущих диагоналей return s + i + 1; // i = наш номер в диагонали } else { return max * max + 1 - GetValue(max - 1 - i, max - 1 - j, max); } } Основной код становится тривиальным: const int max = 3; int[,] matrix = new int[max, max]; for (int i = 0; i < max; i++) for (int j = 0; j < max; j++) matrix[i, j] = GetValue(i, j, max); Результат, понятно, такой же.

Как отсортировать 3 элемента?

#java


Недавно начал учить Java и в качестве практической задачи нужно написать приложение,
которое должна сравнивать 3 возраста и выдавать результат, кто самый старший, младший
и между ними.

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

Я не прошу решения этой задачи, просто подскажите - какие еще варианты решения этой
задачи можно использовать ? Метод решения, на котором настаивает учитель мне не подходит.

public class Loader
{
public static void main(String[] args) {
    Integer damirAge = 30;
    Integer tolanAge = 25;
    Integer uraAge = 55;
    Integer oldest;
    Integer youngest;
    Integer middle;

    if (damirAge >= tolanAge && damirAge >= uraAge)
        oldest = damirAge;
    else if (tolanAge >= damirAge && tolanAge >= uraAge)
        oldest = tolanAge;
    else
        oldest = uraAge;

    if (damirAge <= tolanAge && damirAge <= uraAge)
        youngest = damirAge;
    else if (tolanAge <= damirAge && tolanAge <= uraAge)
        youngest = tolanAge;
    else
        youngest = uraAge;

    if (damirAge >= tolanAge && damirAge <= uraAge)
        middle = damirAge;

    else if (tolanAge >= uraAge && tolanAge <= damirAge)
        middle = tolanAge;
    else
        middle = uraAge;

    System.out.println("Most young " + youngest);
    System.out.println("Middle " + middle);
    System.out.println("Most old " + oldest);
}
}

    


Ответы

Ответ 1



Думаю, что задание предполагало всё-таки освоение логики вложенных операторов if. По анализу математической подоплёки: Возможных результатов (перестановок) может быть 6 (если не учитывать случаи равенства). На получение 6 исходов нужно по меньшей мере 2.58 бита информации, т.е. эта задача требует в идеале выполнения не более трёх сравнений. Это в данном случае реализуемо - сравнений будет 2 или 3 (в среднем 2.667): if A > B: if A > C: if B > C: A B C else: A C B else: C A B else: if B > C: if C > A: B C A else: B A C else: C B A

Ответ 2



Такое странное решение, подходящее для случая именно трёх возрастов: public static void main(String[] args) { Integer damirAge = 30; Integer tolanAge = 25; Integer uraAge = 55; Integer oldest = Math.max(Math.max(damirAge, tolanAge), uraAge); Integer youngest = Math.min(Math.min(damirAge, tolanAge), uraAge); Integer middle = (damirAge + tolanAge + uraAge) - oldest - youngest; System.out.println("Most young " + youngest ); System.out.println("Middle " + middle); System.out.println("Most old " + oldest); } Поскольку внутри Math.max/min по сути своей является условным выражением, это решение можно передалать под вашу задачу с if/else: public static void main(String[] args) { Integer damirAge = 30; Integer tolanAge = 25; Integer uraAge = 55; Integer oldest; Integer youngest; Integer middle; if(damirAge > tolanAge){ oldest = damirAge; } else { oldest = tolanAge; } if(uraAge > oldest){ oldest = uraAge; } if(damirAge < tolanAge){ youngest = damirAge; } else { youngest = tolanAge; } if(uraAge < youngest){ youngest = uraAge; } middle = (damirAge + tolanAge + uraAge) - oldest - youngest; System.out.println("Most young " + youngest ); System.out.println("Middle " + middle); System.out.println("Most old " + oldest); } Но делать нужно конечно через массивы, как ответил @gil9red, на мой взгляд в качестве учебного задания на if/else можно подобрать гораздо более уместные примеры, чем этот.

Ответ 3



просто подскажите - какие еще варианты решения этой задачи можно использовать Условия нужны, но в этой задаче, мне кажется, проще будет другой подход: Получаем 3 возраста Помещаем их в коллекцию, например в список Сортируем список После сортировки, первым элементом будет самый младший, потом средний и последним старший Код: Integer damirAge = 30; Integer tolanAge = 25; Integer uraAge = 55; List ages = Arrays.asList(damirAge, tolanAge, uraAge); System.out.println(ages); // [30, 25, 55] // Сортируем Collections.sort(ages); System.out.println(ages); // [25, 30, 55] Integer youngest = ages.get(0); Integer middle = ages.get(1); Integer oldest = ages.get(2); System.out.println("Most young " + youngest); System.out.println("Middle " + middle); System.out.println("Most old " + oldest); Результат: Most young 25 Middle 30 Most old 55

Ответ 4



Integer damirAge = 30; Integer tolanAge = 25; Integer uraAge = 55; Integer oldest; Integer youngest; Integer middle; if (damirAge >= tolanAge && damirAge >= uraAge){ oldest = damirAge; if (tolanAge >= uraAge){ middle = tolanAge; youngest = uraAge; }else{ middle = uraAge; youngest = tolanAge; } } else if (tolanAge >= damirAge && tolanAge >= uraAge){ oldest = tolanAge; if (damirAge >= uraAge){ middle = damirAge; youngest = uraAge; }else{ middle = uraAge; youngest = damirAge; } }else{ oldest = uraAge; if (damirAge >= tolanAge){ middle = damirAge; youngest = tolanAge; }else{ middle = tolanAge; youngest = damirAge; } } Справедливости стоит добавить что данный алгоритм отработает быстрее чем вариант с сортировкой списка, просто потому что не будем выделять место для списка. В лучшем случае проведем 3 сравнения Integer, в худшем- 5, мат. ожидание примерно равно 4.

К чему относится оператор разыменовывания в Си?

#cpp #c #указатели


В разных источниках встречаю разное написание

int *address_0f_x = &longitude;
int* address_0f_x = &longitude;
int * address_0f_x = &longitude;


Компилируются все варианты, мне нравится второй, но к чему всё-таки правильно относить *? 
    


Ответы

Ответ 1



К переменной. Только это не разыменование, а объявление указателя. Пишите, как хотите, только помните, что int *p1, *p2; объявление двух указателей, а int* p1, p2; указателя p1 и переменной p2 типа int.

Ответ 2



tl;dr; * при объявлении переменной не является оператором разыменования, а является частью составного имени типа; имеет смысл использовать исключительно вариант 3. int * address_0f_x = &longitude; Исторически в С была симметрия объявления переменных-указателей и их использования. Объявляя переменную как int *p можно было сказать, что операция *p дает int. Кроме того, такой синтаксис позволял экономить байты текста в исходниках за счет объявления нескольких переменных в одной строке. Однако с появлением С++ и добавлением в него костылей для обозначения ссылок такая симметрия исчезла. Объявляя переменную как int &p нельзя сказать что операция &p дает int. А необходимости экономии байтов на исходных текстах программ исчезла, соответственно объявление нескольких переменных в одной строке стало индикатором маргинального и потенциально дефективного кода. Таким образом, имеет смысл разделять объявление переменной на ее тип int * и название самой переменной p. Так как тип в общем случае не может быть записан вплотную к идентификатору переменной (например запись intp; будет не корректна), то по соображениям единообразия имеет смысл не делать исключения для составных типов и всегда отделять тип от наименования переменной. По аналогии, так как составляющие типа в общем случае не могут быть записаны вплотную друг к другу (например запись longlongunsignedint будет некорректна), то по соображениям единообразия имеет смысл не делать исключения для частей * & и && и всегда разделять составляющие типа. Ну а еще лучше по возможности использовать алиасы типов, а не составные типы.

Ответ 3



int* p; Тип все тот же int, а * лишь обьявляет, что переменная это не обьект, а указатель на тип. Так что выделяется память не для типа, а память, равному одному машинному слову(независимо от типа), где хранится адрес обьекта. Я бы отнес(мысленно, а не в записи) знак к переменной, хотя сам имею привычку писать по образцу второго варианта.

Как динамически создать переменную, в названии которой может содержаться значение другой переменной?

#python


Нужно создать переменную следующим образом (псевдокод):

Имя_%номер-пользователя% = значение


Как такое сделать?
    


Ответы

Ответ 1



В дополнение к существующему ответу. Динамическое создание переменных сложно поддерживать. И это может быть не безопасно. Вы можете использовать словари. Словари - это хранилища ключей и значений. >>> dct = {'x': 1, 'y': 2, 'z': 3} >>> dct {'y': 2, 'x': 1, 'z': 3} >>> dct["y"] Можно так же использовать имена ключей как переменные >>> x = "spam" >>> z = {x: "eggs"} >>> z["spam"] 'eggs' Для случаев, когда вы думаете о чем-то вроде var1 = 'foo' var2 = 'bar' var3 = 'baz' ... список может быть более подходящим, чем словарь. Список - упорядоченная последовательность объектов с целочисленными индексами: l = ['foo', 'bar', 'baz'] print(l[1]) # prints bar, because indices start at 0 l.append('potatoes') # l is now ['foo', 'bar', 'baz', 'potatoes'] Списки могут быть более удобны, чем словари с целыми ключами. Например добавлять и удалять элементы так удобнее.

Ответ 2



Например, так: import os uid = os.getuid() print(uid) # 1000 try: print(name_1000) except NameError as e: print(e) # name 'name_1000' is not defined locals()[f'name_{uid}'] = 42 print(name_1000) # 42 Но надо помнить, что динамическое создание переменных - это очень плохая практика. Скорее всего, задуманное надо реализовывать через ассоциативные структуры данных (словарь, например). В зависимости от задачи, переменная может быть создана не только в локальной, но и в глобальной области видимости с использованием функции globals.

Как определить, лежат ли точки на одной прямой?

#алгоритм #c


Задаем координаты 4 точек с клавиатуры (x и y).
Как написать условие, которое определяет лежат ли хотя бы три из этих точек на одной
прямой?     


Ответы

Ответ 1



Можете воспользоваться уравнением прямой проходящей через две точки: (x - x_1) / (x_2 - x1) = (y - y_1) / (y_2 - y_1) Если, уравнение будет выполнятся для какой либо другой точки - она находится на этой прямой UPD: Собственно для трех точек условие будет выглядеть так: if ((x_3 - x_1) / (x_2 - x_1) == (y_3 - y_1) / (y_2 - y_1)) /*Точки 1, 2, 3 - лежат на одной прямой */

Ответ 2



Все правильно кроме знака "==". При задании координат точек мы всегда округляем результат до точности, предусмотренной системой компьютерной алгебры или языком программирования. Поэтому на практике крайне редко выполняется подобное равенство. Разве что, если взять точки (1,2); (2,4); (3,6) и т.п. Правильно задаться точностью вычислений Tol и сравнить с ней разницу результатов: Tol = 1e-10 //По требованиям задачи или задать как входной параметр if abs((x_3 - x_1) / (x_2 - x_1) - (y_3 - y_1) / (y_2 - y_1)) <= Tol // Точки лежат на прямой Второй вариант, обычно более быстрый: Tol2 = 1e-20 //Квадрат допустимой погрешности if ((x_3 - x_1) / (x_2 - x_1) - (y_3 - y_1) / (y_2 - y_1)) ^ 2 <= Tol2 // Точки лежат на прямой Можно еще правильнее. Подсчитать коэффициенты уравнения прямой между точками 1 и 2, а далее вычислить "расстояние от точки до прямой". Алгоритм легко гуглится. Если это расстояние меньше Tol, значит точка лежит на прямой. Однако для большинства задач это - излишнее усложнение.

Ответ 3



Для целочисленных координат можно использовать формулу: bool function IsPointsOnLine(int x1, int y1, int x2, int y2, int x3, int y3) { return (x3 * (y2 - y1) - y3 * (x2 - x1) == x1 * y2 - x2 * y1); } или тоже самое, но с кешированием: void PreIsPointsOnLine(int x1, int y1, int x2, int y2, int& dx, int& dy, int& ds) { dx = x2 - x1; dy = y2 - y1; ds = x1 * y2 - x2 * y1; } bool IsPointsOnLine(int dx, int dy, int ds, int x3, int y3) { return (x3 * dy - y3 * dx == ds) } Для четырёх точек можно перебрать четыре условия, поочерёдно исключая одну из точек: bool function IsPointsOnLine(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) { if (IsPointsOnLine(x2, y2, x3, y3, x4, y4) || IsPointsOnLine(x1, y1, x3, y3, x4, y4) || IsPointsOnLine(x1, y1, x2, y2, x4, y4) || IsPointsOnLine(x1, y1, x2, y2, x3, y3) ||) { return true; } return false; } Для того, чтобы не было переполнения, числа не должны быть близки к границам целочисленного типа переменной.

Ответ 4



Вариант с погрешностью предложенный v_mil не работает. Если кому вдруг понадобится: Уравнение прямой через две точки: (x-x1)/(x2-x1) = (y-y1)/(y2-y1) отсюда: x*(y2-y1) + x1*(y1-y2) + y*(x2-x1) + y1*(x2-x1) = 0 таким образом для уравнения прямой Ax + By + C = 0 имеем A = y2 - y1 B = x1 - x2 C = x1 * (y1 - y2) + y1 * (x2 - x1) Расстояние от точки M (x, y) до прямой считаем по формуле: d = Math.Abs(A * Mx + B * My + C) / Math.Sqrt(A^2 + B^2) Вот это расстояние уже можно сравнивать с некой величиной погрешности.

Случайные числа в C++

#cpp


Помогите создать программу, чтобы при нажатии на определенную кнопку, он выдавал
числа по рандому, с нажатием кнопки я разобрался, вот выложил код, а как сделать чтобы
он не прибавлял +5, а просто каждый раз выдавал разные цифры. Я прочитал статьи про
рандом в интернете, но не понял к сожалению, там не на доступном языке и непонятно.
#include 
#include 

using namespace std;

int main ()
{
    int b=0; char c;

    while ((c=getch()) !='q')
    {
        if (c=='a') {
            b+=5;

            cout << b << endl;
        }
    }

    system ("pause");
    return EXIT_SUCCESS;
}
    


Ответы

Ответ 1



В C++11 есть классы для генерации случайных чисел: #include #include std::default_random_engine rng; int my_random(int a, int b) { std::uniform_int_distribution dist_a_b(a, b); return dist_a_b(rng); } int main() { rng.seed(std::random_device()()); std::cout << my_random(0, 42); } uniform_int_distribution

Ответ 2



Еще добавлю, что, так как вывод этого числа заключен в цикл, можно использовать случайное число относительно текущего времени. Это делается примерно так: подключаем библиотеки #include и #include затем генерируем случайное число, предварительно создав переменную текущего момента времени t: time_t t; srand((unsigned) time(&t)); int random = rand()%MAX; Вот недавно проверил, полностью рабочий код: #include #include #include using namespace std; void main(){ int MAX = 10; time_t t; srand((unsigned) time(&t)); int random = rand()%MAX; cout< #include #include using namespace std; void main(){ int MAX = 10; int i=0; srand((unsigned) time(NULL)); while(i!=10){ int random = rand()%MAX; cout<

Ответ 3



Как получать в С++ случайные числа. Пример. #include #include srand (time (NULL)); int rand_num = rand();

25 / 100 = 0, Почему?

#c_sharp #cpp #c


Мне нужно по некой формуле высчитать результат, но это не удается потому что в ней
используется деление числа 25 на число 100.
Все это выглядит примерно так:  

double i = 25 / 100; // В этом случае будет выводиться 0, а мне нужно 0.25


В чём здесь проблема?
    


Ответы

Ответ 1



У Вас в действии int-операнд 25 делится на int-операнд 100. Соответственно и деление происходит целочисленное. Для ожидаемого Вами результата необходимо хотя бы один из операндов привести к типу double. Например: double i = 25 / 100d;

Ответ 2



потому что это инт. double i = 25.0 / 100; либо приведите (cast) к double, наверное это делается так: double i = (double)25 / 100;

Ответ 3



Измени свой код на: double i = 25 / 100d; Иначе компилятор считает, что выполняется целочисленное деление, которое в данном случае вернет 0 вместо 0.25.

Как правильно можно узнать количество определенных символов в String/Integer'e?

#java


Коллеги, вопрос такой:
Как правильно можно узнать количество определенных символов в String/Integer'e?
Допустим есть строка 1110001101011 - мне нужно из нее узнать кол-во единиц или нулей,
как на Java это сделать? Стандартных методов нет...    


Ответы

Ответ 1



Наверное самый простой способ будет посимвольный разбор строки и сравнение каждого элемента отдельно, что-то вроде: String str = "1100011"; int countNulls=0, countOnes = 0; for (char element : str.toCharArray()){ if (element == '0') countNulls++; if (element == '1') countOnes++; }

Ответ 2



Регулярно не выражаться! import java.util.*; import java.lang.*; class Main { public static void main (String[] args) throws java.lang.Exception { String string = "1110001101011"; Map map = new HashMap(); for ( int i = 0; i < string.length(); i++ ) { Integer n = map.get( string.charAt(i) ); if ( n == null ) map.put( string.charAt(i), 1 ); else map.put( string.charAt(i), ++n ); } System.out.println(map); } }

Ответ 3



Если эффективно, то цикл. Если штатно - то есть готовый метод - countMatches. Прям с демками. В общем случае лучше предпочитать готовые библиотечные функции, так как обычно они уже достаточно хорошо работают. И только если они не удовлетворяют по скорости/качеству (либо просто нет таких), тогда писать свой велосипед. Но если это учебное задание, то тогда нужно писать так, как хочет преподаватель, и не важно, эффективно или нет, так как для некоторых преподавателей важно, что бы они понимали решение. Но ещё я в условии заметил слово "Integer". Но в Integer'e нет символов (при желании их конечно можно найти там, например рассматривая Integer как 4 (или 2) char. Но это что то не то:)

Ответ 4



данное решение позволяет считать любые символы, у вас есть возможность самому задавать символы которые нужно посчитать. теоретически должно работать с приемлимой производительностью: public class CountCharacters { public static void main(String[] args) { // two usage examples for provided input string countCharacters("1110001101011", '0', '1'); countCharacters("1110001101011", new char[] {'0', '1'}); // usage example for custom string countCharacters("00112233445566778800qwertyuiop[]{}asdfghjkl;'zxcvbnm,./", '0', '1', 'a', 'b', 'c'); } private static void countCharacters(String inputString, char... interestedCharacters) { final int[] occurences = new int[256]; final char[] array = inputString.toCharArray(); for (final char c : array) { occurences[c] = occurences[c] + 1; } // dump results for characters you are interested in for (int i = 0; i < interestedCharacters.length; i++) { System.out.println("found '" + occurences[interestedCharacters[i]] + "' occurences for character '" + interestedCharacters[i] + "'"); } System.out.println(); } } выводит в консоль: found '5' occurences for character '0' found '8' occurences for character '1' found '5' occurences for character '0' found '8' occurences for character '1' found '4' occurences for character '0' found '2' occurences for character '1' found '1' occurences for character 'a' found '1' occurences for character 'b' found '1' occurences for character 'c' p.s. минусы, - неоптимальное использование памяти + нет поддержки кодировок. в принцыпе последнее можно легко исправить аналогичным образом работает решение для int'ов: private static int[] ALL_DIGITS = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; protected static void countNumbers(int i) { countNumbers(i, ALL_DIGITS); } protected static void countNumbers(int value, int... digits) { // number consists of only 10 digits int[] occurences = new int[10]; // copy value int x = value; while (x >= 10) { int low = x % 10; occurences[low] = occurences[low] + 1; x = (x - low) / 10; } occurences[x] = occurences[x] + 1; // dump results for digits you are interested in for (int i = 0; i < digits.length; i++) { System.out.println("found '" + occurences[digits[i]] + "' occurences for digit '" + digits[i] + "'"); } System.out.println(); } пример использования: countNumbers(111000110, 0, 1); countNumbers(1234567890); результат: found '4' occurences for digit '0' found '5' occurences for digit '1' found '1' occurences for digit '0' found '1' occurences for digit '1' found '1' occurences for digit '2' found '1' occurences for digit '3' found '1' occurences for digit '4' found '1' occurences for digit '5' found '1' occurences for digit '6' found '1' occurences for digit '7' found '1' occurences for digit '8' found '1' occurences for digit '9'

Ответ 5



import java.util.regex.Matcher; import java.util.regex.Pattern; public class OneZero { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub String s = "1011110011"; Pattern pattern = Pattern.compile("1"); Matcher matcher = pattern.matcher(s); int n = 0; while (matcher.find()) { System.out.println(matcher.group()); n++; } System.out.println("N = " + n); } } Выводит количество единиц в консоль 1 1 1 1 1 1 1 N = 7

Переписать или отлаживать дальше? [закрыт]

#best_practice


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

Вот собственно хочу спросить совета у бывалых, что лучше делать в таких случаях:
пытаться дописать, довести до ума получившееся "УГ" или все-таки лучше взять и переписать
все на чистовик, абы сверкало и не глючило?  

Просто я так подумал, если я так все время буду делать, это ж сколько времени уйдет
даром, если так вот код переписывать всякий раз, когда мне в нем что-то не нравится.
    


Ответы

Ответ 1



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

Ответ 2



Часто прогеры мечутся между двумя крайностями: Первая крайность: пытаются заведомо нерабочий код сделать рабочим разнообразными примочками, мелкими правками и проч. В итоге код запутывается до невозможности Вторая крайность: перфекционизм - несмотря на то что код рабочий вылизывают код до потери пульса или же подгоняют под какой-нибудь приличный паттерн. Функционал при этом остается прежним, а трудозатраты растут. Я для себя выработал несколько правил: а. Если код работает - то стараюсь не вносить мелкие улучшения. Правило: "Не трогай то что работает!" б. Код подлежит замене, если его расширение/модификация привносит проблемы - это сигнал к пересмотру кода (даже если код работает). Правило: "модификации должны быть гладкими" в. Если править код, то надо править конкретно! Правило: "лучше 1 большое изменение, чем 10 маленьких" Исходя из этого я бы определил, что код автора подлежит замене - согласно правилам а) и б)

Выбор технологии для будущей работы [закрыт]

#c_sharp #aspnet #wpf #net #работа


        
             
                
                    
                        
                            Закрыт. Этот вопрос не по теме. Ответы на него в данный
момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он соответствовал тематике «Stack Overflow на русском».
                        
                        Закрыт 4 года назад.
                                                                                
           
                
        
Имеется несколько лет опыта с платформой .NET (в основном проекты WinForms на C#).
Сейчас хочу перейти на другую технологию этой же платформы (по причине устаревания
WinForms и сокращения кол-ва проектов под неё), но не могу определиться с выбором:
WPF или ASP.NET. Попробовал их и обе довольно интересны, но не могу понять, что ближе
по душе. Понятно, что разница очевидна - программирование веб-проектов или десктопных,
но я в сомнениях.
А на ваш взгляд, что более интересно и перспективно?

WPF
ASP.NET WebForms
ASP.NET MVC

Ответ прошу прокомментировать.
Заранее благодарен за ответ!    


Ответы

Ответ 1



Сам я программирую под WPF. Технология интересная, но требует много знания различных моментов, очень долго учить. Если бы у меня был шанс сделать свой выбор раньше (а раньше с интернетом у меня были проблемы), то я все же выбрал ASP.NET MVC или Java. Хотя WPF тоже ничего, только вакансий на него не так много - следовательно не так востребован. Но с WPF можно легко пересесть на Silverlight, а лучше если понравился XAML, сразу начинать с него. С другой стороны если начать с ASP.NET то можно заодно поднять и HTML, CSS, JavaScript jQuery. Так что выбор очевиден - ASP.NET или (и) CMS какой-нибудь. Вот я как себе это представляю (сугубо мое видение:) ) ASP.NET MVC -> HTML (CSS) -> SQL -> (jQuery) -> CMS -> Silverlight -> (WPF) - уровень PHP (MySQL) -> CMS -> jQuery (AJAX) - (просто и) интересно WPF -> Silverlight -> ASP.NET - эксклюзивно (my) Objective-C - перспективно C++ -> ASM32 -> DisASM -> HACK 0101001010 - не советую хД C++ -> Qt - серьезный С++ C++ -> Android SDK - скучно не будет Java -> JavaFX - очень хорошая технология Flash - без комментариев Unity3D - советую любителям игр Может что забыл напомните, дополню (и исправлю если что). Жду комментов

Ответ 2



ИМХО более перспективно web. Я бы выбрал ASP.NET MVC. Причины очень просты. В последнее время намечена тенденция перемещения данных в облака, открывается множество сервисов, которые предоставляются посредством веб. Рынок настольных приложений, конечно, всё также популярен, но наибольшим спросом сейчас пользуются именно веб- и мобильные технологии.

Ответ 3



Еще один голос за веб. Мой совет: ASP.NET MVС. И действительно - облачные сервисы сейчас популярнее коробочных версий. Их проще поддерживать и пользователю ничего не нужно устанавливать для того, чтобы пользоваться продуктом. Открыл браузер и вуаля)

operator new

#cpp


Вот такой вопрос для любителей С++ in depth. 
Приходилось кому-либо в своих проектах определять собственный operator new, operator
new[] и т.п. или встречать в чужом коде? Если да, то с какой целью это было сделано?    


Ответы

Ответ 1



Я переопределяю new/delete в расширениях ПО, т.е. в динамических библиотеках, в которых используется STL и/или библиотеки, наследующие ее модель динамической памяти. Думаю, проблема "многокучности" известная, когда при инициализации CRT, в каждом модуле создается своя куча, которой пользуются глобальные методы управления памятью. Вот, чтобы расширения могли свободно интегрироваться во всех модулях ПО, и переопределяются операторы new/delete. Для этого, основной модуль экспортирует 2 метода, в которых вызывает malloc и free, соответственно, а каждое расширение переопределяет свой new/delete, вызывая в них эти 2 метода. Получается, что если расширения используют только глобальные new/delete, они все используют только одну кучу. А для корректной работы статических объектов, использующих кучу при инициализации, я перекрываю точку входа в DLL, импортируя эти 2 метода перед инициализацией CRT, после чего передаю управление встроенной _DllMainCRTStartup. Но есть нюанс, кторый нужно учесть при такой подстановке: первое, что нужно вызвать в точке входа - __security_init_cookie(): BOOL WINAPI MyDllStartup( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved ){ __security_init_cookie(); if( !::MyDllMainPreCRTStartup( hinstDLL, fdwReason, lpReserved ) ){ return FALSE; } return _DllMainCRTStartup( hinstDLL, fdwReason, lpReserved ); } p.s.: вместо malloc и free можно вызывать глобальные new/delete, это уже не принципиально.

Ответ 2



Было дело. Переопределял new для подсчета выделяемой памяти. Помнится тем же способом пытался ловить утечки памяти. И как-то пробовал писать свой менеджер памяти. В общем переопределять new скорее для развлечения. В реальных задачах это в общем-то не нужно.

Ответ 3



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

Ответ 4



В своих. Допустим, есть такая задача: приложение должно захватывать столько памяти, сколько сказано в конфиге, не больше. Точнее даже так: при старте захатывается кусок памяти, и всё выделение идёт только внутри него. Потом, в некоторых случаях вешается сторонний CG, в некоторых - нужна своя отладка выделения/освобождения...

Ответ 5



Я использовал, чтобы некоторые классы размещались в специальном хранилище, которое чистится при завершении потока. Там в деструкторах не было ничего, кроме уничтожения зависимых объектов, смысл был в том, чтобы убрать всё это крохоборство из деструкторов в менеджер памяти, который зачищает всю память оптом. Опыт скорее не понравился. Много писанины, польза туманна. На сегодняшний день имею мнение, что интегрировать внутрь класса логику размещения в памяти бессмысленно. Если хочешь принудить класс к работе через нестандартный менеджер памяти — закрой конструкторы и создавай экземпляры особой фабрикой. Если классу размещение не важно, нестандартный менеджер доступен через размещающий конструктор. А встраивание new/delete в класс — странная херня, смесь бульдога с крокодилом. Сказанное не относится к переопределению глобальных new/delete, с которыми свой геморрой, но есть и польза.

Ответ 6



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

Ответ 7



Да, приходилось. Но больше в embedded: дефолные реализации звали malloc()/free() тогда как нужно было использовать аллокатор RTOS (ThreadX). В другом проекте с той же RTOS был ещё и свой аллокатор с хитрой аллокацией памяти дабы уменьшить фрагментацию и сократить оверхеды на блочные выделения. Плюс тут же был простенький анализатор мемликов и логирование аллокаций. Первый случай - проект сам поднимал, поэтому и сам писал. Второй случай - уже было сделано. В своих были только эксперименты, что бы некоторые типы объектов выделялись из специального пула. Из популярного, всякие valgrind подменяют вызовы new/malloc/delete/free в целях анализа утечек, повреждений.

Паттерн ООП, ограничивающий количество экземпляров класса по аттрибуту

#ооп #многопоточность #шаблоны_проектирования


Как организовать невозможность в программе существования нескольких экземпляров одного
класса с одинаковым значением определенного атрибута? 
Как называется такой паттерн ООП (если он есть)?
Пишу приложение на JAVA, многопоточное, но примеры интересны на различных языках
программирования (естественно с ООП парадигмой).    


Ответы

Ответ 1



В общем случае наиболее подходит под вашу задачу паттерн Factory. В частном случае, когда разрешен всего 1 объект это классический Singleton. Единственное, я бы не стал возлагать на паттерн задачу безопасности ибо что Singleton, что Factory ломаются на раз-два. Update Применительно к Java такой способ ведь действительно существует и часто используется в реальной жизни - например кэширование пула коннектов (например JDBC). Как известно, коннект ресурс достаточно дорогой и ценный и если по ходу пьесы коннект берется во многих местах имеет смысл организовать кэширование коннектов с ограничением количества оных. Вполне аналогично также и ставится ограничение на количество окон в системе. Да в том же Android'е надысь писал такую штуку. Ставится корневой класс - прародителей всех Activity и вперед создавать списочек, контроль все как надо. Так что надо попроще и без кошачьих завихрений, а то совсем ужо замутили головы boost commiter, перегрузка операторов... P.S. Ну вы млин даёте :)

Ответ 2



Эта задачу (если решать ее в общем виде) очень сложно решить хорошо в языках с Garbage Collector'ами в силу недетерминированности работы последних. Под хорошим решением подразумевается что-то типа специальной фабрики ObjectFactoryWithAttributeChecking, в которой хранятся слабые ссылки на объекты выбранных типов, и при попытке создания нового объекта она проверяет, жив ли прошлый / прошлые или нет. Понятно, что, в силу недетерминированности GC очень легко получить ситуацию, когда на объект уже никто не ссылается, но он еще не заколлекчен (и в этот момент фабрика ObjectFactoryWithAttributeChecking будет вести себя некорректно). Плохой подход - вводить такую же фабрику с явными методами Create и Dispose - решает задачу, но сводит на нет преимущества автоматической сборки мусора и крайне неустойчив. Если calling site в случае такого подхода забудет вызвать Dispose, то ваша фабрика моментально оказывается в неконсистентном состоянии. Если задача поставлена из соображений отладки, то самый верный путь решения заключается в инжектировании своего кода в аллокатор на низком уровне. .NET, например, допускает такие штуки для решения задач профайлинга, но, в случае выбора такого подхода каждый кейс нужно рассматривать индивидуально. В случае языков без сборки мусора (типа C++) вроде как можно реализовать решение на уровне собственного аллокатора, но сделать это правильно для всех кейсов крайне нетривиально. Такая задача должна быть по зубам разработчиками уровня boost commiter, да и то, наверняка, не всем. Небольшой Update: Сейчас еще раз перечитал вопрос и, в принципе (если вас устроит такой подход), вы можете просто сделать фабрику ленивых синглтонов - т.е фабрику с методом getObjectWithSomeConcreteAttribute, которая будет создавать объект с таким атрибутом только один раз по его первому запросу. Создание объектов в обход фабрики в таком случае, разумеется, надо запретить. Другое дело, что это не слишком интересно, если сравнивать с задачей, решения для которой я предлагаю выше :)

Ответ 3



Есть такой вариант решения "проблемы", недостатки такого подхода очевидны, хотя вариант имеет право на жизнь (видел в нескольких enterprise продуктах): public enum TestEnum { INTEGER { @Override public void doAction(Object arg) { if (arg instanceof Integer) { System.out.println("int - " + arg); } } }, STRING { @Override public void doAction(Object arg) { if (arg instanceof String) { System.out.println("str - " + arg); } } }, BOOLEAN { @Override public void doAction(Object arg) { if (arg instanceof Boolean) { System.out.println("bool - " + arg); } } }; public abstract void doAction(Object arg); public static void applyAction(Object arg) { System.out.println("Handling: '" + arg + "'"); for (TestEnum e : values()) { e.doAction(arg); } } public static void main(String args[]) { List objects = new LinkedList(); objects.add("ab"); objects.add(Integer.valueOf(1)); objects.add("cd"); objects.add(Integer.valueOf(2)); objects.add(Boolean.valueOf(true)); objects.add(Integer.valueOf(3)); objects.add("ef"); for (Object object : objects) { TestEnum.applyAction(object); } } }

Как в Java обойти все директории на диске без рекурсии?

#java


Помогите, пожалуйста, найти способ в Java обойти все директории на диске без рекурсии?
У меня как на зло без рекурсии ничего не выходит.    


Ответы

Ответ 1



File rootDir = new File(root); List result = new ArrayList<>(); Queue fileTree = new PriorityQueue<>(); Collections.addAll(fileTree, rootDir.listFiles()); while (!fileTree.isEmpty()) { File currentFile = fileTree.remove(); if(currentFile.isDirectory()){ Collections.addAll(fileTree, currentFile.listFiles()); } else { result.add(currentFile.getAbsolutePath()); } }

Ответ 2



Делаете список директорий. Изначально он пустой. Берете в качестве текущего элемента начало списка. Заполняете его директориями, лежащими в корне диска. Пока не дошли до конца списка: получаете директории для текущего элемента, добавляете их в список сразу после текущего. Таким образом, когда вы дойдете до конца - у вас будет список всех директорий. Причем отсортированный так, как если бы мы обходили дерево рекурсией: C:\A C:\A\A C:\A\A\A C:\A\A\B c:\A\B C:\B c:\B\A и.т.п.

Ответ 3



Попробуйте так (псевдокод) queue taskList = new queue(); taskList.add(startDir); while (!taskList.empty()) { string dir = taskList.first(); taskList.popFirst(); for each dirEntry in dir { if entry is directory taskList.add(entry); else processFile(entry); } } А вообще, почитайте про обходы дерева, например, BFS/DFS.

Ответ 4



Код на скорую руку, но рабочий: import java.io.File; public class Main { public static void main(String[] args) { String rootDir = "d:\\"; File root = new File(rootDir); File[] files = root.listFiles(); int i = 0; while(i

Ответ 5



Обход всех каталогов без стека и рекурсии. Добавляем корень в пустой Массив i=0 (начало Массива) Если i-й элемент Массива каталог, то добавляем все его елементы в конец Массива i=i+1 Если i < длины массива, то переход к пункту 3

Ответ 6



очень удобно такую задачу делать со стеком. изначально в стек ложится корневая папка. дальше алгоритм такой: 1) выталкиваем последний элемент 2) получаем для папки список подпапок, добавляем все в стек 3) если стек не пустой повторяем пункт 1

Ответ 7



Начиная с Java 1.7 import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; public class FileTree { public static void main(String[] args) { Path pathSource = Paths.get("Введите сюда путь к какому-либо каталогу, содержащему другие каталоги и файлы"); try { Files.walkFileTree(pathSource, new MyFileVisitor()); } catch (IOException e) { e.printStackTrace(); } } } class MyFileVisitor extends SimpleFileVisitor { public FileVisitResult visitFile(Path path, BasicFileAttributes fileAttributes) { System.out.println("file name:" + path.getFileName()); return FileVisitResult.CONTINUE; } public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes fileAttributes) { System.out.println("Directory name:" + path); return FileVisitResult.CONTINUE; } } The Java™ Tutorials - Walking the File Tree

Ответ 8



попробую расписать свой код подробно можно так для директорий #! /usr/bin/env python #coding=utf-8 import os #----------------------------------------------------- # Формирует список поддиректорий от текущей директории # на один уровень ниже #----------------------------------------------------- def getCurrDir(rootDir=''): currListDirs=[]; onlyDirsLst=[] currListDirs=os.listdir(rootDir) for i in range(0,len(currListDirs)): currListDirs[i]=(rootDir+'/'+currListDirs[i]) if os.path.isdir(currListDirs[i])==True: if os.path.islink(currListDirs[i])==False: # добавляем только дирректорию (исключая ссылки) onlyDirsLst.append(currListDirs[i]) return onlyDirsLst #--------------------------------------------- # Формирует список поддиректорий, начиная от текущей rootDir # на всю глубину дерева дирректорий #--------------------------------------------- def getLstAllDirs(rootDir=''): oldLst=[]; newLst=[]; currPosLst=0 oldLst.append(rootDir) while True: try: newLst=getCurrDir(oldLst[currPosLst]) for i in newLst: oldLst.append(i) currPosLst+=1 except IndexError: return oldLst или так для директорий и всех в них файлов #-------------------------------------------------------------- # Возвращает кортеж, где первый список - файлы, второй - каталоги # Для одного уровня ниже от rootDir #-------------------------------------------------------------- def getCurrFileDir(rootDir=''): currListDirs=[]; onlyDirsLst=[]; onlyFilesLst=[] currListDirs=os.listdir(rootDir) for i in range(0,len(currListDirs)): currListDirs[i]=(rootDir+'/'+currListDirs[i]) if os.path.isdir(currListDirs[i])==True: if os.path.islink(currListDirs[i])==False: onlyDirsLst.append(currListDirs[i]) else: if os.path.isfile(currListDirs[i])==True: if os.path.islink(currListDirs[i])==False: onlyFilesLst.append(currListDirs[i]) return onlyFilesLst, onlyDirsLst #-------------------------------------------------------------- # Возвращает кортеж, где первый список - файлы, второй - каталоги # Для всех уровней от rootDir; # Если Lst=getLstAllFilesDirs(...), то кортеж Lst==([fa,fb,..],[da,db,..]) # Lst[0]==[fa,fb,..] - список файлов; # Lst[0][1] - второй файл в списке файлов. # Lst[1]==[da,db,..] - список каталогов; # Lst[1][5] - шестой каталог в сп. каталогов. #-------------------------------------------------------------- def getLstAllFilesDirs(rootDir=''): oldLst=([],[]); newLst=([],[]); currPosLst=0 oldLst[1].append(rootDir) while True: try: newLst=getCurrFileDir(oldLst[1][currPosLst]) for i in newLst[1]: oldLst[1].append(i) for i in newLst[0]: oldLst[0].append(i) currPosLst+=1 except IndexError: return oldLst ----------------------- проверяем: cDir='/home' print '= Ждём. Обработка =============================' Lst=getLstAllFilesDirs(cDir) print 'Список файлов:' print '========================' for i in range(len(Lst[0])): print '%4d: %s'%(i,Lst[0][i]) print '=================================================' print 'Список каталогов:' print '========================' for i in range(len(Lst[1])): print '%4d: %s'%(i,Lst[1][i]) print '=================================================\n' print ' Каталоги другой функцией (отсортированные)' print '== Ждём. Обработка ==============================' Lst=getLstAllDirs(cDir) Lst.sort() for i in Lst: print i

Запятые и точки в дробных числах в си при вводе чисел

#c #локаль


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


Ответы

Ответ 1



На самом деле многие библиотечные функции используют текущую локаль. В частности, от текущей локали зависит, какой разделитель целой и дробной части ожидают увидеть функции. При запуске программа наследует системную локаль, похоже в вашем случае это русская локаль. В качестве демонстрации приведу программу: #include #include #include #include void test(const char* str) { printf("%s => ", str); char* endptr; double num = strtod(str, &endptr); // Checking if whole string parsed if (endptr != str + strlen(str)) { printf("ERROR"); } else { printf("%lf", num); } printf("\n"); } void locale_info() { printf("Current locale: %s\n", setlocale(LC_NUMERIC, NULL)); printf("Current delimiter: '%s'\n", localeconv()->decimal_point); } int main() { const char* dot = "10.5"; const char* comma = "10,5"; setlocale(LC_ALL, "en_US.utf8"); locale_info(); test(dot); test(comma); setlocale(LC_ALL, "ru_RU.utf8"); locale_info(); test(dot); test(comma); } У меня программа выводит: Current locale: en_US.utf8 Current delimiter: '.' 10.5 => 10.500000 10,5 => ERROR Current locale: ru_RU.utf8 Current delimiter: ',' 10.5 => ERROR 10,5 => 10,500000 Видно, что в зависимости от локали, программа по разному интерпретирует одни и те же данные. Чтобы избежать таких неожиданностей, можно при запуске программы устанавливать стандартную локаль для числовых данных: setlocale(LC_NUMERIC, "C");

Выбор элемента select при помощи jQuery

#jquery #html #css


У меня такая проблема:
Есть Select:
 

И я прописал js код в консоль:
$("#make [value='Mazda']").attr("selected", "selected");

Возвращет нужный элемент option, selected="selected", но я смотрю на список, а выбран
все равно первый option(value=0).
$("#make [value='Mazda']").attr("selected", "");

Тот же результат, помогите пожалуйста, как сделать так, чтобы визуально был выбран
элемент с value='Mazda', естественно он должен быть выбран и по настоящему.    


Ответы

Ответ 1



Рискну предположить, что это некая особенность реализации JS в Chrome. Ваш код вполне успешно выполняется под IE (10-ая версия) и Firefox (23-я). А вот в Chrome (28-я) происходят описанные вами проблемы. В Opera не проверял. Так или иначе, с помощью вот такого чудо-костыля: var val = text = 'Mazda'; $("select option[value=" + val + "]").attr('selected', 'true').text(text); добытого мною исключительно методом тыка, это можно обойти. Не могу сказать, за счет чего это работает (люди, лучше знакомые с JS, думаю, смогут это как-то объяснить). Вероятно, это действительно адов костыль, тем не менее, может сойти за временное решение

Ответ 2



В текущих версиях jQuery для смены option в select и выбора checkbox надо использовать метод .prop() $('select option[value="Mazda"]).prop('selected', true); Данный метод изменяет свойство javascript объекта соответсвующего option и не добавляет атрибуты, то есть в разметке ничего не изменится. Хотя добавление атрибута пока, что работает с option (проверил в Opera), но не работает с checkbox.

Ответ 3



Попробуйте $('#make').val('Mazda')

Ответ 4



Для изменения таеих вещей как selected и checked, надо использовать prop, а не attr.

Ответ 5



$("#make").val("Mazda").change()

Ответ 6



Туго понял вопрос но возможно $("#make option[value='Mazda']").val('Mazda').attr("selected", true);

Ответ 7



Лично я предпочитаю следующий метод однострочник: $("select").val("").trigger("chosen:updated") Во всех браузерах должно работать. Соответственно вместо пустой строки нужно использовать текст первого option'а, но как правило дефолтный option должен быть пустым, а не содержать 0 и т.п. Соответственно подставляя значение любого option'а его можно выбрать.

Ответ 8



Нужно применять атрибут selected к элементу option: $("#make>option[value='Mazda']").attr("selected", "selected");

Ответ 9



$("#make").val("Mazda"); Это все.

Что означает “опыт коммерческой разработки” на С++

#cpp


Какие нужны знания что бы утверждать, что есть опыт коммерческой разработки на С++.
Просьба, не писать необдуманных ответов.    


Ответы

Ответ 1



В общем-то элементарно - опыт коммерческой разработки С++ подразумевает работу С++-программистом, причем вне зависимости от типа - будь то работа в офисе, удаленная работа, фриланс или какие-то другие формы сотрудничества, в том числе и без трудового договора или договора найма (то есть важен именно опыт таковой работы. Хотя, весьма возможно, что опыт фрилансерской деятельности может по разным причинам цениться ниже. Однако же его тоже можно отнести к пресловутому "опыту коммерческой разработки"). Разумеется, написание лабораторных работ по 500 рублей за штуку сюда не входит, и это еще один критерий - имеет значение скорее всего сам факт разработки сколько-нибудь существенного ПО, а следовательно и понимания принципов разработки и способность кандидата подтвердить свои навыки. Возможно, что собеседующего (ведь речь о вакансиях, не так ли?) устроит и факт деятельного участия в каком-нибудь более-менее существенном опенсорсном проекте (хотя не уверен - для некоторых собеседующих, а уж тем более рекрутеров даже факт наличия богатого прошлого на Гитхабе или регулярные коммиты в ядро Linux мало о чем скажет (несколько утрирую, но, думаю, мысль понятна)). В общем, в основном "опыт коммерческой разработки" - это (помимо опыта работы и записи в трудовой книжке) то, что отличает студента без опыта от хотя бы джуниора, и позволяет понять, что соискатель занимался чем-то более серьезным, нежели курсовые проекты, формошлёпство и велосипедостроение

Ответ 2



это значит только одно - приложение, которое разрабатывалось, прямо или косвенно приносило деньги. То есть: приложение продавалось Вами непосредственно. приложение продавалось фирмой, которая платила Вам зарплату. приложение было "бесплатным" сервером, а для доступа к нему, людям нужно было покупать отдельное (не зависящее от Вас) приложение, например, клиент на адроиде. Отсюда вывод. Вам не знания нужны, а просто список приложений. То есть, ответ должен быть такой: "работал N лет в фирме ABC, которая делала продукт ZZZ (можно посмотреть на сайте www.previouscompany.com). Я в этом продукте делал функциональность YYY".

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

#php


Всем привет. Есть дата в базе данных. При выборке данных получают такую дату - 
2014-10-22.
Как преобразовать это в нормальный вид, чтобы было 
22.10.2014 г.
Люди добрые, помогите!    


Ответы

Ответ 1



date("d.m.Y", strtotime('2014-22-10'))

Ответ 2



MySQL DATE_FORMAT("2014-10-22",'%d.%m.%Y')

Ответ 3



В запросах неудобно, придется постоянно повторять при каждом случае шаблон форматирования, удобнее запрашивать unix_timestamp(column), а затем уже сразу форматировать результат одной на весь сайт функцией php; Ну и, соответственно, при записи, опять же, возложить проблему на db engine и, преобразовав в timestamp полученную дату, посылать ее в from_unixtime($column);.

Что такое HANDLE в программировании под windows?

#windows


Что такое HANDLE? Я начал путать его с контекстом устройства. Но что-то мне подсказывает,
что это разные вещи.    


Ответы

Ответ 1



HANDLE - дескриптор, т.е. число, с помощью которого можно идентифицировать ресурс. С помощью дескприторов можно ссылаться на окна, объекты ядра, графические объекты и т.п. Можно провести аналогию с массивом: у нас имеется набор ресурсов, а HANDLE - это индекс, который указывает на конкретный ресурс. Это все, конечно, абстрактно, но думаю идея понятна.

Ответ 2



Вы не работаете с контекстом устройства напрямую. Сам по себе контекст устройства - "черный ящик", что у него внутри, мы не знаем. У контекста устройства есть хэндл (идентификатор), который, например, возвращают функции CreateDC и GetDC и который можно передать в другие WinAPI функции. Получается, контекст устройства (DC) - некий сложный объект, а хэндл контекста устройства (hDC) - число. Хэндл контекста устройства - это один из видов (частный случай) хэндлов. Кроме хэндлов DC, есть хэндлы окон, файлов, битмэпов, всяких кистей/карандашей и т.д.

Ответ 3



Любой контекст может быть обозначен хендлом, но не всякий хендл ссылается на контекст устройства. Хендл - это просто указатель. Контекст - это уже часть памяти, где хранятся различные настройки, параметры и данные связанного "устройства".

Java. Создание объекта. Советы про использование String

#java


Я недавно начал изучать Java и у меня возникло несколько вопросов. 


Мне непонятно почему в Java  нет простого механизма (метода) ввода\ вывода  чего
либо. То есть когда в Pascal - это write\read или Python - print\input. В Java есть
стандартное средство вывода - System.out.println, но ввод нужно реализовывать через
импорт Scanner.
Подскажите это я чего-то не понимаю или реально в таком мощном языке
нету таких базовых методов?
Также как я понял Scanner подходит лишь для текста, а что  если мне нужно вводить
числа? Что использовать? Можно полностью написать как это будет выглядеть. 
Объясните пожалуйста, что значат аргументы в этой команде.

public static void main(String[] args)

Можно объясните принцип создание экземпляра класса. Например: 

String variable = new String ("Text");  


Почему почему дважды вызывается класс String в начале и при создании?
Я понимаю, что можно просто смирится и все, но мне не понятно зачем это действие,
есть для этого объяснение или это сделано просто так?

    


Ответы

Ответ 1



Java - объектно-ориентированный язык в отличие от Паскаля, и его богатая система классов ввода-вывода, базирующаяся на потоках (streams), позволяет использовать одни и те же механизмы для любых ситуаций: работа с консолью, работа с файлами, работа с сетью, работа с архивами. Раз речь зашла про класс Scanner - обратимся к документации. Класс предоставляет кучу методов для разных ситуаций: String next(String pattern) - вернет строку, если она соответствует шаблону; boolean nextBoolean() - вернет значение булева типа; int nextInt() - вернет целочисленное значение; float nextFloat() - вернет значение с плавающей точкой типа float. Это не все, то умеет Scanner, но теперь вы знаете, где искать. Это не команда. Это объявление публичного (public - доступного всем) статического (static - доступного без создания экземпляра класса) метода main, который принимает массив строк (String[] args) и ничего не возвращает (void). Согласно спецификации, метод с такой сигнатурой является точкой входа в вашу программу. То есть, при запуске в командной строке java MyClass выполнение программы начнется с этого метода в классе MyClass. В качестве массива args будут переданы аргументы из командной строки. Например, при запуске java MyClass foo bar массив args будет иметь значение ["foo", "bar"]. почему дважды вызывается Класс String в начале и при создании String variable = new String ("Text"); Класс не "вызывается", класс нельзя "вызвать". В данном случае происходит три действия: Объявляется переменная variable типа String. Создается новый экземпляр типа String через конструктор с одним аргументом "Text". Переменной variable присваивается ссылка на созданный объект. В случае со строками это можно было сократить до вида: String variable = "Text"; PS. Крайне рекомендую начать изучение Java, вооружившись одним из учебников для начинающих, там есть ответы на подобные вопросы: Книги по Java и другая литература PPS. В следующий раз, пожалуйста, соблюдайте правила и задавайте по одному вопросу за раз.

Ответ 2



В java все вводы/выводы основаны на потоках и их реализациях для консоли, файла и т.д. Чтение/запись в консоль - частный случай работы с потоками. Scanner - класс, имеющий в себе реализацию чтения чего-либо из потока. Но из консоли читать не только с его помощью можно. Аргументы String[] args - это те параметры, которые будут переданы в метод при вызове его из коммандной строки. Т.е. если будет вызов вида java MyClass param1 param2, то args - это строковый массив, содержащий строки param1 и param2. Если вызов происходит без параметров, этот массив будет пустым. Первый String - указание типа объявляемой далее переменной variable. В java имеет место статическая типизация, в отличие от Python. И в отличие от паскаля, где сначала объявляются все переменные, а затем происходит их использование, в java возможно объявление переменных в любом месте, главное чтобы до их непосредственного использования. Второй String - это вызов конструктора класса String с передачей ему параметра. В результате получаем объект класса String, который присваивается переменной variable.

Ответ 3



1 простых методов типа write\read в Java нет. Ввод чисел можно сделать так: Scanner scanner=new Scanner(System.in); String st=scanner.nextLine(); int i=Integer.parseInt(st); 2 это аргументы командной строки с которыми запускается ваше приложение. 3 первое слово String задает тип переменной variable, new String ("Text") создает новый объект String. Вообще можно сразу и не инициализировать variable: String variable; /...какой-то код.../ variable=new String("text");

Ответ 4



Проблема с выводом не ясна. Чтобы что-то вывести в консоль просто пишите System.out.println(ТУТ_ЧТО_ТО); В качестве аргумента (ТУТ_ЧТО_ТО) можно подставить или примитив или объект. В последнем случае он будет автоматически преобразован с строку и выведен в консоль. В метод main передаётся массив строк, являющихся параметрами для запуска программы. Например, запуская через командную строку, вы можете передать что-то и получить это в качестве аргкумента метода main. Класс не вызывается дважды. Сначала объявляется его тип, указывается имя переменной-ссылки, после чего создаётся объект и присваивается этой переменной-ссылке. Сделано так, а не иначе т.к. java - язык со строгой типизацией. Например в php тип переменной не указывают и вы можете всё что угодно ей присвоить. И никакой компилятор вас не одёрнет, если вы попытаетесь сложить число 1.(3) со строкой "Вася".

Подсчитать максимальное количество отрицательных элементов идущих подряд

#cpp #массивы


Нужно подсчитать максимальное количество отрицательных элементов идущих подряд. Что-то
не могу понять как сделать правильно. На данный момент считает просто все отрицательные
элементы.

#include 
#include
using namespace std;

void main()
{
    setlocale(LC_ALL, "ukr");
    srand(time(NULL));
    const int n = 15;
    bool change = true;
    int arr[n], m = 0;

    for (int i = 0; i < n; i++)
    {
        arr[i] = rand() % 10 - 5;
        cout << arr[i] << " ";
    }
    cout << endl;
    int maxcount = 0;
    for (int i = 0; i < n; i++)
    {
        int count = 0;
        if (arr[i] < 0) {
            for (int j = i; j < n; j++)
            {
                if (arr[j] < 0) {
                    count++;
                    if (count > maxcount) { maxcount = count; }
                    cout << count << " ";
                }
            }
        }
    }
    cout << endl << maxcount << endl;
}

    


Ответы

Ответ 1



for (int j = i; j < n; j++) { if (arr[j] < 0) { count++; if (count > maxcount) { maxcount = count; } }else{ count = 0; //cбрасывать значение count кто будет? } } пробный запуск: -3 -5 -4 3 4 -5 1 0 -3 -1 -1 -2 -5 -5 0 6

Ответ 2



Чуточку функциональщины на любителя: #include int main() { int v[] { -2, 0, 2, -1, -2, -11, -2, 3, 5, 1, -1, -1, 1, -2, -1, 2 }; int m = ranges::max(v | ranges::view::group_by([](int a, int b){return (a < 0) && (b < 0);}) | ranges::view::transform(ranges::distance) ); assert(m == 4); } Вот если бы еще диапазоны в стандартную библиотеку заапрувили.. Да ещё и с параллельными алгоритмами.. Ммм...

Ответ 3



int main() { int a[12] {-1, -2, -11, -2, 3, 5, 1, -1, -1, 1, -2, -1}; unsigned current = 0, maxnegative = 0; for (int i = 0; i < 12; ++i) { if (a[i] < 0) { ++current; if (current > maxnegative) maxnegative = current; } else { current = 0; } } cout << maxnegative << endl; return 0; }

Ответ 4



Может кому то реактивный вариант понадобится: #include #include int main() { std::vector v{ -1, -2, -11, -2, 3, 5, 1, -1, -1, 1, -2, -1, 1, 2, 1, 0 }; auto m = rxcpp::observable<>::iterate(v) .scan(0, [](int a, int i) { return (i < 0) ? a + 1 : 0; }) .scan(0, [](int a, int i) { return std::max(a, i); }) .distinct_until_changed(); m | rxcpp::operators::subscribe(rxcpp::util::println(std::cout)); } Фишка в возможности использования входных данных, растянутых по времени. При каждом появлении во входном потоке нового значения, если результат меняется, наблюдатель получит событие. То, что это ультросовременно и риактивно, наверное и так понятно )

Вытаскивание IP из строки

#python


Допустим у меня есть строка типа такой:

from rw-sc-22 (wellknown [94.26.18.9])


Как с помощью инструментов Python без изобретания велосипеда я могу вытащить из нее
IP-адрес ?
    


Ответы

Ответ 1



регулярным выражением import re str = "from rw-sc-22 (wellknown [94.26.18.9])" result = re.search('\[(\d+\.\d+\.\d+\.\d+)\]', str) print result.group(1)

Ответ 2



Из данной строки, простейший метод такой: mystr = "from rw-sc-22 (wellknown [94.26.18.9])" mystr.split("[")[1].split("]")[0]

Java generics как работает?

#java #generics


Я пишу:

Class a = n.getClass();


Метод getClass() должен вернуть объект описывающий класс и присвоить его переменной а.

Но вот это часть мне не понятна Class. Что это за тип переменной
такой и куда переменную а теперь вообще можно использовать?
Хочу понять как это работает. Помогите разобраться. 
особенно  знак вопроса убивает здесь что-то общее с тернарной операцией?
    


Ответы

Ответ 1



Примеры Обозначение типа параметра public static double sumOfList(List list) { double s = 0.0; for (Number n : list) s += n.doubleValue(); return s; } public static void printList(List list) { for (Object elem: list) System.out.print(elem + " "); System.out.println(); } Поле класса и тип возвращаемого значения public class ClassContainer { private List list; public ClassContainer(List list){ this.list = list; } public List getList(){ return this.list; } }

Ответ 2



Нет, что вы, нет здесь тернарной операции)) ? extends Object - означает, что здесь может быть любой класс, унаследованный от Object. Вот аналогичная запись: List>

Ответ 3



В коде где используются обобщённые типы знак вопроса ? называется шаблоном поиска (wildcard) и представляет собой неизвестный тип. Этот символ используется в различных ситуациях: обозначает тип параметра, поля класса или типа локальной переменной, тип возвращаемого значения. Есть определённые ограничения его применения.