Хочу научиться языку Java c нуля, нужен совет


Доброго времени суток. Обращаюсь к вам с нестандартной просьбой, помочь и подбором онлайн курсов (видео, текст) по языку Java c нуля, а то стыдно быть уже безмозглым уебаном. Сложность в том, что мне уже под 30, а программирование не было ни на одном этапе учебы.

Обращаться в личку к Андрею Устиновичу

Теги:#совет@ponydobrota #научусь@ponydobrota

Если у вас есть какая-нибудь просьба, но некого спросить, то можете обратиться нам по следующему адресу: http://vk.com/ponydobrota
DIY Brony взаимопомощь – место, где всегда тебе рады.
Как правильно запостить просьбу на Табуне смотрите описание этого блога.
Как правильно запостить просьбу на паблике смотрите здесь: http://vk.com/topic-64079792_31305616
Если будут у вас какие-нибудь вопрос насчет заполнения просьбы, то обращайтесь в личку Никите Длиннокотову (https://vk.com/id269502965)

157 комментариев

В ленту!
Blankhead
0
— Кастую фестрала @cab404 в топик.
Orhideous
0
Совет 1.
Нн учи яву.
SL-RU
-3
Да ладно? Море полезных приложений, кроссплатформенность не стоят этого?
d64
0
кроссплатформенность

О да! Я тоже любил это «магическое» слово, эдак лет 7 назад.
А потом понял что оно нафиг не нужно. Смотри в сторону web.
idem_id
+2
О, корифеи в треде.
Lurgee
0
Java не единственный язык, обладающий этими свойствами.
Wolfram
+1
Все остальные не webscale, ну кроме джаваскрипта!
Hibonicus
0
JavaScript != Java
"!=" — не равно (для не прогеров)
Ghost_Russia
+1
Далана?
Hibonicus
+1
Asm, C, C++ тоже кроссплатформенные, да ещё какие! На них написанна Java машина.
А по опыту того, кому приходилось запускать эти «кроссплатформенные» приложения на Linux серверах, скажу, брехня всё это. Мне доказывал программист(который кроме джавы и слышать ни о чём другом не хочет) что это приложение работает везде, но тестил он только в винде и ислользовал кучу библиотек и фреймворков, у которых либо версия по linux не совпадала, либо просто не работала.
Ghost_Russia
-2
Он тралил наверное тебя
Hibonicus
0
Неа. Это препод в универе и он реально помешан на джаве. У них тут проект загнулся из за того что его интерфейс на джаве не смог на средней мощности компах отрисовывать 2д анимации как в win8 и изображение с вебки. Всё ужасно лагало.
Ghost_Russia
0
Какой проект?
Hibonicus
0
Простой, для универа. Отображение информации и новостей для студентов на моноблоках.
Ghost_Russia
0
чёто сомнительная история какая-то
Hibonicus
+1
Честно, сам в шоке. Но у него там захват с камеры, отрисовка с камеры(вроде в разных потоках) и анимации при нажатии на кнопки(они все сдвигаются в сторону при нажатии). Я им несколько раз предлагал написать интерфейс на чём нибудь другом(C#, C++) и как ты думаешь? Хрен.
Ghost_Russia
0
Надо было на джаваскрипте писать!
Hibonicus
0
И правда! html + css + js для того что они делали, вполне бы вкатило. Даже отображение с вебки.
Ghost_Russia
0
Справедливости ради, можно на чем угодно написать так, чтобы лагало :)
Abaduaber
+2
чёт фигня какая-то. С вебки я совсем недавно изображение дёргал через какую-то опенсорсную либу, всё было зшбс.

И про кроссплатформенность тоже фигня. Всё прекрасно работает, если аккуратно написать.
sleeply4cat
+1
хотел написать тонкий webscale-троленк, но его тут нету, и вообще мне лень, так что мне пофиг
Hibonicus
+1
webscale

— Тонко. Ну просто планковская толщина.
А теперь говори, кто ты и куда дел настоящего Гиба?
Orhideous
0
Я его изнасиловал, расчленил и смыл в универтаз
Hibonicus
0
И что значит «планковская»?
Hibonicus
0
Lurgee
0
tl;dr скажи блин прямо что это такое
Hibonicus
0
1,6·10^−35 метров
Lurgee
0
метров

Ты сейчас человека еще больше запутаешь. :)
Как говорил мой препод по эл.теху на консультации к экзамену: «Списывать можете откуда угодно, кроме википедии, которую наполняют бездумные копипастеры.»
Defbie
+1
Java — не самый лучший язык для начинающего. ООП, конечно, штука полезная, но начинать думать на нём тяжело. Сначала — алгоритмы, базовые вещи вроде переменных, циклов и альтернатив. Чистый C или Pascal вполне подойдут. Потом уже можно двигаться в сторону объектов, интерфейсов, фреймворков и всего такого.
Удачи.
NTFS
0
давно не писал циклов, лал
Hibonicus
0
Месье веб-мастер или SQL-программист?
NTFS
+1
webscale-програмист
Hibonicus
0
Не, сначала — ассемблер, мне кажется.
Lurgee
+1
Не, сначала наноигла раскалёная! /s
Hibonicus
0
Неплохой совет, кстати. Понимать, во что в итоге транслируются все эти красивые конструкции, никогда не помешает, да и от GOTOбоязни хорошо лечит.
NTFS
0
от GOTOбоязни хорошо лечит.
Hibonicus
0
Я не знаю этого мема :-)
NTFS
0
Это значит «нет»
Hibonicus
0
GOTO — это обычный jmp. Суть единственный способ в процессоре передать управление куда-то, кроме следующей команды. Так что ничего бесовского в нём нет, если, конечно, не переходить вверх по коду, впрочем, и это иногда бывает удобно.
NTFS
+1
Это актуально только для микрошей, во всех остальных случаях тебе за это нож между рёбер воткнут, и правильно сделают
Hibonicus
0
А вы, наверно, и двойной цикл оборачиваете в процедуру, чтобы прервать его через return, или используете флажки, как во времена мейнфреймов?
NTFS
0
Пример приведи
Hibonicus
0
Первая же ссылка из поисковой выдачи.
Не цикл, но тоже хороший пример.
DrSchmallhausen
0
int first_negative_value = 0 ;
for (int i=0; i<m; i++)
    for (int j=0; j<m; j++)
        if (matrix[i,j])<0) {
            first_negative_value=matrix[i,j] ;
            goto finish ;
        }
            
finish:
      if (first_negative_value==0) printf("Not found\n") ; else printf("first negative: %d\n",first_negative_value) ;


Одна команда безусловного перехода в нужном месте — лучше, чем переменная-флаг или процедура-обертка.
NTFS
0
Спасибо, поблевал
module Main where

import Data.List

firstNeg :: [[Int]] -> Maybe Int
firstNeg ((x:xs)) = case find (<0) x of 
							Just val -> Just val
							Nothing -> firstNeg xs
firstNeg _ = Nothing

Hibonicus
+1
Я не владею Python, но тут похоже на функциональное программирование. Это уже иная парадигма, как сравнивать танк и самолет.
NTFS
0
Я не владею Python, но тут похоже на функциональное программирование.
Какая связь между тем что было перед запятой, и тем, что после неё?
Hibonicus
0
Пришел гиб и все опошлил.
Liksys
0
Maybe Int

Лол. Может, инт, а может, не инт…
BUzer
+1
Не, скорее «Может есть, может нет»
Hibonicus
0
А чем так хуже?
int first_negative_value = 0 ;
for (int i=0; i<m; i++)
    for (int j=0; j<m; j++)
        if (matrix[i,j])<0) {
            first_negative_value=matrix[i,j] ;
            i = m;
            break;
        }

if (first_negative_value==0) printf("Not found\n") ; else printf("first negative: %d\n",first_negative_value) ;
Wolfram
0
тем, что
i=m ;


есть неявное дублирование кода. Если придется код модифицировать, и цикл по i будет идти от 0 до, к примеру, func(m) — ты 100% забудешь обновить эту строку, в итоге все посыпется.
NTFS
0
Ок, согласен, тут не получается нормально без goto. Флаги таскать тоже не очень приятно:
int first_negative_value = 0 ;
bool flag = true;
for (int i=0; i<m&&flag; i++)
    for (int j=0; j<m; j++)
        if (matrix[i,j])<0) {
            first_negative_value=matrix[i,j] ;
            flag = false;
            break;
        }

if (first_negative_value==0) printf("Not found\n") ; else printf("first negative: %d\n",first_negative_value) ;
Wolfram
0
Hibonicus
0
Победа.
Стоп, а зачем i = m?
0x1042E
0
Чтобы из предидущего цикла выйти, говнокод короче
Hibonicus
0
Починил?
int first_negative_value = 0 ;
for (int i=0; i<m; i++)
{
    for (int j=0; j<m; j++)
    {
        if (matrix[i,j])<0)
        {
            first_negative_value=matrix[i,j] ;
            break;
        }
    }
    if(first_negative_value < 0) 
    {
        break;
    }
}

if (first_negative_value==0) printf("Not found\n") ; else printf("first negative: %d\n",first_negative_value) ;
0x1042E
0
Тут проблема в том, что если надо будет поменять внутреннюю логику того, что под первым ифом, то и второй тоже придётся менять (что опять же легко забыть).
Wolfram
0
Напомнить документацией?
0x1042E
0
Кстати, аналогично если усложнить это все то во всех гото будешь путаться.
0x1042E
0
Ну это уже зависит от радиуса кривизны рук. Запутаться шансов в goto, используемом таким способом, не больше, чем в break. Я, кстати, не думая, сделал бы точно так же, только с флагом и писал бы второй иф в одну строчку:
int first_negative_value = 0;
bool found = false;
for (int i=0; i<m; i++)
{
    for (int j=0; j<m; j++)
    {
        if (matrix[i,j])<0)
        {
            first_negative_value=matrix[i,j];
            found = true;
            break;
        }
    }
    if(found) break;
}

if (first_negative_value==0) printf("Not found\n") ; else printf("first negative: %d\n",first_negative_value) ;

Но вариант с goto, на мой взгляд, смотрится лучше.
Wolfram
0
Точнее, даже так:
int first_negative_value;
bool found = false;
for (int i=0; i<m; i++)
{
    for (int j=0; j<m; j++)
    {
        if (matrix[i,j])<0)
        {
            first_negative_value=matrix[i,j];
            found = true;
            break;
        }
    }
    if(found) break;
}

if (!found) printf("Not found\n") ; else printf("first negative: %d\n",first_negative_value) ;
Wolfram
0
Скажи плз плз, меньше какого m должен быть i или я не уловил суть этого примера? М-да, затупил
crestwoodarcher
0
m — это какая-то константа или переменная, определённая в программе выше этого куска кода — размер квадратной матрицы matrix.
Wolfram
0
Да я тут F# занялся, понял уже про ранг\размер\дефайн в ваших языках.
Ох, зря я матан прогуливал… Блин, язык классный, на самом деле — чистейший матанализ в его простейшей вариации: только запиши в среду и готово!

(Расчет графика экспоненты от нуля до одного с dx=10^(-3) поточечно занял C#-программой ~5*10^-2 сек, на F# ~ 5*10^-6 сек, на входе в i7 было 10^3 значений, все ядра включены, турбобуст выкручен в заводской предел, я просто удивлен, какой хороший язык и как его легко интерпретировать)
crestwoodarcher
0
Какой блядь бред, какой блядь матан?
Hibonicus
+1
Ты пони маешь, что ты полную херь написал?
Hibonicus
0
ЯЗЫК МАТЕМАТИЧЕСКИЙ НОТАЦИЙ, ТЫ ШТО, НЕ ЗНАЕШЬ, КАК СЧИТАТЬ ПРЕДЕЛЫ ЛОПИТАЛЕМ ММММММММММ??????????
crestwoodarcher
0
Зачем считать пределы?
Hibonicus
0
Чтобы получить представление о поведении функций, не производимых в точке их нулей
crestwoodarcher
0
А зачем тебе получать представление о поведении функций, не производимых в точке их нулей? Где это нужно?
Hibonicus
0
Задана матрица A = [0,0.1,0.2,...,0.1*m] m is int from 1 to 10000
Вопрос — по заданной матрице найти значение функции (x^2-x\sgn(x); X is A; Y) во всех доступных точках. В точке «0» функция теряет смысл, но методом анализа по Коши можно вытянуть предел лопиталем, причем легко — разводим предел + лопиталь, получаем доопределение — (f;x of X = 0; y of Y = 0).
Теперь вопрос №2 — нахуя, если руками можно доопределить? Для подобной матрицы, только m from 1 to 64^64 определить все доступные значения для функции и предсказать ее поведение в незаданных точках с емкостью операции меньшем, чем olittle(x(max)^2) (sin(x*pi))/(sgn(x)-sgn(y)); X is A; Y). ВЕЛКАМ ТУ ЕР СЛОМАННЫЙ МОСК
crestwoodarcher
0
Сам делай своё дз
Hibonicus
0
Расчет графика экспоненты от нуля до одного с dx=10^(-3) поточечно занял C#-программой ~5*10^-2 сек, на F# ~ 5*10^-6 сек,

Что-то не очень правдоподобная разница, интересно, за счёт чего она достигается?
Wolfram
0
За счёт… эм… не самого оптимального алгоритма на сишарпе.
DrSchmallhausen
0
Вот я тоже так подумал. (На C# вообще есть встроенный алгоритм для этого?) Либо за счёт точности вычислений.
Wolfram
0
Не имею понятия, я сишник/ассемблерщик вообще, и не пытаюсь даже лезть в языки высокого уровня — как минимум, дальше чем необходимо для успешной трансляции в машинный код (в это время года я у мамы компиляторщик).
DrSchmallhausen
0
Процессор просто считает значения, никаких свистоплясок. F# оче годный язык особенно для маткадов, аутокадов и пр. — расчеты и перерасчеты даже для real-time в тысячи раз быстрее
crestwoodarcher
0
Ну как просто, это ещё алгоритм надо быстрый придумать. (Там он встроенный, я так понимаю.) Я могу попробовать разложить экспоненту в ряд Тейлора, оставить только первые несколько членов так, чтобы остальные не влияли на требуемую точность, а затем считать поточечно схемой Горнера. Вот интересно, насколько это будет медленнее F# на C++, скажем (при той же точности)?
Wolfram
0
Я пока не проверял(нуп 18-летний, шо ты хочищь), только как ты собрался экспоненту раскладывать в ряд Тейлора и при каком x0?
crestwoodarcher
0
Если на отрезке от нуля до одного посчитать надо, то в нуле. А в чём проблема разложить экспоненту в ряд Тейлора?

По поводу скорости я спрашиваю, потому что когда разница существенная, объяснение иногда бывает не самое приятное для языка, на котором быстрее. Не так давно видел статью на Хабре, где было показано, что какая-то платная библиотека ресайзит картинки быстрее, чем свободная ImageMagick, раз в 400. А разгадка была в том, что делают они это разными методами, и качество изображения у ImageMagick получается лучше.
Wolfram
0
Для такой мелочи может goto и подойдет.
0x1042E
0
Ну как мелочи, в программах иногда встречаются навороченные вложения циклов, из которых в некоторых случаях полезно быстро выйти и продолжить выполнение. Приходится либо тащить булеву переменную через цепочку break'ов, либо запихивать часть циклов в функцию (что бывает удобно, если она используется в разных кусках кода, но это не всегда так) и выходить return'ом, либо использовать goto.
Wolfram
0
вообще-то в нормальных языках нету ни брейков, ни ретурнов, ни гото!
Hibonicus
0
#define нормальных
DrSchmallhausen
0
Я такие не учил.
Wolfram
0
let hibo = [hi; bo; ni; cus]
ley stop = map (fun x = {x; st|op|trall|ing}
crestwoodarcher
0
hibonicus -> hibonicus -> IO hibonicus
Это я описал в типах как я себе отсасываю!
Hibonicus
0
А вот тут надо на проектировку смотреть. Вложенные циклы не есть хорошо.
0x1042E
0
Предложи другой способ обхода двумерной матрицы. Нет, можно конечно представить двумерную матрицу как одномерную, но зачем?
NTFS
0
Предложи другой способ обхода двумерной матрицы.

Как будто он всего один, а не один из факториала от количества элементов.
Ход конём, кривая Гильберта, псевдослучайная последовательность наконец.
DrSchmallhausen
0
И баттхерт человека, который потом будет сопровождать этот код :-) он тебя самого конем поставит.
NTFS
0
Обфускация, сэр! =)
Ну и кстати, организовывать данные в различные пеановские кривые — идея не такая уж плохая, например для задач где необходима двумерная локальность по кэшу.
DrSchmallhausen
0
Как старый ООП-щик, я бы еще ввел класс Матрица как коллекцию классов Ряд и Колонка, с общими Ячейками — но все эти предложения представляют собой известный антипаттерн — Ненужная Сложность.
NTFS
0
И интерфейсы!
Hibonicus
0
Не, интерфейсы по большому счету бесполезны. Если нужно использовать совершенно разные объекты схожим образом, лучше выделять дополнительные классы или использовать паттерн Стратегия. Впрочем, это уже вопрос методологии, я в основном на паттерны и TDD ориентируюсь, у фунциональных подходов свои фишки.
NTFS
0
Если размерность матрицы изначально не задана, тогда, вместо того чтобы писать кучу вложенных циклов, можно написать правило перехода от одного массива к следующему типа (0,0,0,0)->(0,0,0,1)->(0,0,0,2)->(0,0,1,0)->(0,0,1,1)->… в отдельной функции, а затем уже в качестве i брать такой массив. Хотя для двух так делать нецелесообразно.
Wolfram
0
Ну да, паттерн Итератор. Можно применить в условиях, когда данные хоть чуть сложнее примитивов int. Для двух циклов и целой матрицы — либо goto, либо флаг, либо процедура.
NTFS
0
Я не могу это прочитать
Hibonicus
0
Почему?
0x1042E
0
всё мутно очень для человеческого моска
Hibonicus
0
Плохо написал или тебе лень думать?
0x1042E
0
запутано и непоняшно
Hibonicus
0
Расслабился ты.
0x1042E
0
Почему нельзя так?
int first_negative_value = 0 ;
for (int i=0; i<m; i++)
    for (int j=0; j<m; j++)
        if (matrix[i,j])<0) {
            first_negative_value=matrix[i,j] ;
            finish(first_negative_value);
            break;
        }
            
function finish(first_negative_value){
      if (first_negative_value==0) printf("Not found\n") ; else printf("first negative: %d\n",first_negative_value) ;
}

или мы без функций?
Ghost_Russia
0
Функция тут вообще не к месту, с таким же успехом можно скопировать нижнюю строчку в середину. Проблема в том, что мы не выйдем из внешнего цикла, и он напечатает по одному отрицательному значению для каждого i.
Wolfram
0
Будте проще:
int first_negative_value = 0;
top_level: for (int i=0; i<m; i++)
    for (int j=0; j<m; j++)
        if (matrix[i][j])<0) {
            first_negative_value=matrix[i][j];
            break top_level;
        }
if (first_negative_value == 0) printf("Not found\n");
else printf("first negative: %d\n", first_negative_value);

Хотя да, у вас же не java :)
Revizor
+1
Кстати, спасибо, для java отличное решение, добавлю в коллекцию.
NTFS
0
Питонобоги смотрят с недоумением на говнокод выше.
Предлагаю:
import itertools
first_negative_value = None
for i in itertools.chain(*matrix):
    if i < 0:
        first_negative_value = i
        break


Или даже так:
import itertools
if min(itertools.chain(*matrix)) >= 0:
    print("Not found")
else:
    print("We have some negative values!")
Liksys
+2
— Второй вариант красивее. Но можно ещё досыпать функциональщины, по вкусу.
Orhideous
0
((min(itertools.chain(*matrix)) >= 0 and (print("Not found") or 1)) or print("We have some negative values!"))

print({True:"Not Found",False:"We have some negative values"}[min(itertools.chain(*matrix)) >= 0])

Liksys
0
— Это однострочники.
any(itertools.map(lambda subchain: filter(lambda x: x < 0, subchain), chain))
Orhideous
0
— Хотя можно и list comprehension, я не уверен, что тут быстрее, а cProfile лень перед сном расчехлять.
Orhideous
0
map() не в итертулсе лежит, дес.
Liksys
0
— Угу. Перепутал с выпиленным apply, с ним покрасивее вышло. Ладно, пренебречь: ещё одна причина не кодить сонным.
P.S. А код я таки прогнал бы на профайлере.
Orhideous
0
map и filter нельзя использовать, в том и фича что при первой встрече нужного элемента нужно вернуть его, а map и filter всегда обходят весь список/массив
Hibonicus
0
Кстати, первое — вполне себе функциональщина.
Liksys
0
Проснулся. Вспомнил ещё более интересный вариант. Python-Python, отпусти меня…
[a for b in chain for a in b if a < 0]
Orhideous
0
Наркоманить — так по полной.
Liksys
0
Наркоманить — так по полной.

Ну ладно. Внимание, однострочник на Си.
for (int x = m * m - 1; (x + 1 || printf("Not found\n") & 0x100) && (matrix[x / m][x % m] >= 0 || printf("%d, %d\n", x % m, x / m) & 0x100); --x);
DrSchmallhausen
0
Жаль отредактировать уже нельзя, ну пусть хоть так
for (int x = m * m - 1; (x + 1 || !printf("not found\n")) && (matrix[x / m][x % m] >= 0 || !printf("%d, %d\n", x % m, x / m)); --x);
DrSchmallhausen
0
itertools.chain

Библиотечная функция, да? Читер.
NTFS
0
Используешь ide-шку? Читер!
Используешь ооп? Читер!
Пишешь на языке программирования, а не в машинных кодах? Читер!
Lurgee
+1
Я с некоторой иронией это все пишу. Понятно, что желающих использовать HEX-редактор вместо VCL уже нет, просто за библиотечными «деревьями» бывает не видно собственно леса.
NTFS
0
Кстати, когда я писал на шарпе в универе, использовал только вим)
Liksys
0
шарп офицально признали недоскалой
Hibonicus
0
Все системщики уставились на этот комментарий с неодобрением.
DrSchmallhausen
+1
К слову: ассемблерный SIMD-код, наоборот, ещё как эту боязнь прививает =)
DrSchmallhausen
0
Хочу научится языку Java c нуля, нужен совет
Сначала научитесь русскому языку. Потом беритесь за ассемблер.
GL_DOS
-1
так он же на анлийском
Hibonicus
0
Чортд. Это, кстати, мой фейл, не автора.
Blankhead
0
Тут кстати, даже пост такой был, вроде.
*Кастует линк*
Линкtabun.everypony.ru/blog/121984.html — прошу вас
MolniaKseroX
0
На жабараше есть.
javarush.ru
Сначала тоже думал, тип жаба, кроссплатформенность. Потом до меня дошло, что я собираюсь только модифицировать Minecraft и мне достаточно основ. Ну я и забил. Может ты дальше меня пройдешь :D
ddclash
0
Поздно начинать, тем более с джавы.
jikho
0
1)Начинать никогда не поздно
2)Я раньше изучал джаву и написал только калькулятор и моды для майна
3)Начни еще изучать с++
Derpy_Hooves_X
0
Моды для майна пишутся на раз-два с MCP. Один гайд и ты уже умеешь создавать предметы, блоки, броню, хавчик и прочую хрень.
Я остановился на создании мобов.
ddclash
0
Ты что, пытался ему кроме первичного интелекта, а-ля *иди к игроку когда будет в такой-то зоне* пытался ему дополнительное что-то приписать?

Опыта нет, просто спрашиваю
MolniaKseroX
0
BigMackintosh
+6
это к петухам
Hibonicus
+1
Ась?
BigMackintosh
0
Ты чоооо, на bsdшку поставь nginx, хер уронишь. Можешь забить весь канал, но 502 не получишь никогда.
ddclash
0
А у меня плазма упала
Alreagoon
-1
Качай книги и читай
CornerPin
0
Я один методом тыка освоил кучу языков?)
Ghost_Russia
0
Это работает тока с пхпплеадой!
Hibonicus
+3
Liksys
0
— Два таких топика уже было на хабре. Теперь Табун?
Orhideous
0
Ты погоди, появятся треды про неработающие однострочники.
Liksys
+2
— А я бы почитал срачики про stateless-код. Может, есть в заначке?
Orhideous
+2
Найн.
Liksys
0
нужен совет

Совет: на завод иди.
Lee
-3
-1

Мамин фрилансур порвался.
Lee
0
Фрилансур?
Hibonicus
0
–2.
DrSchmallhausen
0
Погромисты посрались. Хороший тред.
ncuxonam
0
— награждается сей пост, за неплохой, специфичный срач.
Автор — вам бы посоветовал книжеций почитать, те же гайды можно и самому найти. Было бы желание
К тому же отзывы найти думаю также не трудно, а они могут вам подсказать, стоит ли игра свеч
El_World
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.
Скрыто Показать