Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Я хочу получать рассылки с лучшими постами за неделю
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
Создавая аккаунт, я соглашаюсь с правилами Пикабу и даю согласие на обработку персональных данных.
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр
Реалистичный симулятор игры бильярд. Играйте в Бильярд 3D: Русский бильярд, как в настоящей бильярдной!

Бильярд 3D: Русский бильярд

Симуляторы, Спорт, Настольные

Играть

Топ прошлой недели

  • Rahlkan Rahlkan 1 пост
  • Tannhauser9 Tannhauser9 4 поста
  • alex.carrier alex.carrier 5 постов
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

Нажимая кнопку «Подписаться на рассылку», я соглашаюсь с Правилами Пикабу и даю согласие на обработку персональных данных.

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
0 просмотренных постов скрыто
1418
user10963650
20 дней назад
Лига программистов

Я создал полностью бесплатный ресурс с туториалами по Java, покрывающий весь backend-роадмап. Делюсь и жду мнений!⁠⁠1

Всем привет! Принес вам длиннопост Пикабушники :)

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

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

Я создал полностью бесплатный ресурс с туториалами по Java, покрывающий весь backend-роадмап. Делюсь и жду мнений! Обучение, Программирование, IT, Развитие, Разработка, Java, Курсы, Бесплатно, Курсы java, Онлайн-курсы, Бесплатное обучение, Халява, Изучение, Обучение детей, Интересные сайты, Полезные сайты, Создание сайта, Веб-разработка, Гифка, Длиннопост

Бесплатный курс по Java.

Примерно пару лет назад, когда я еще заканчивал университет и думал о будущей работе, у меня возникла идея сделать обучающее мобильное приложение, которое охватит актуальный roadmap по Java бекенд-разработке – и подготовлюсь к собесу, и сделаю что-то полезное, двух зайцев одним выстрелом, так сказать.

Приложение должно было стать эдакой шпаргалкой по всему roadmap: короткие уроки, в каждом из которых без воды отражается суть того или иного класса, функции и т.д., с примерами, каждый из которых показывал бы конкретный реальный кейс применения технологии. То есть я не хотел делать утомительные лекции, или сухую документацию. Мне хотелось создать пояснения для себя с минимумом текста, но максимально отражающие суть, насколько это возможно, при этом сохраняя стилистическую грамотность и достаточность пояснений – ведь это потом будут читать люди. То есть это должны были быть скорее не лекции а уроки чтобы если чтото забыл быстро перечитать и уловить суть.

Ну вот, например — все знают, чем отличается абстрактный класс от интерфейса, это легко найти на любом сайте. Но вот полностью понять, когда использовать интерфейс, а когда абстрактный класс, чтобы в процессе разработки не возникало вопросов, – уже сложнее. Мне хотелось выписать все возможные кейсы, когда пригодится одно, а когда другое, и отразить это в коротких примерах. Чтобы потом, готовясь к собесу, не искать это долго на StackOverflow и подобных ресурсах.

Несколько месяцев я тщательно шерстил подборки вопросов на собеседования, различные форумы, чтобы разобраться во всем необходимом для интервью. В итоге получилась большая подборка из 200 уроков, покрывающая весь roadmap Java-бэкенда.

Я создал полностью бесплатный ресурс с туториалами по Java, покрывающий весь backend-роадмап. Делюсь и жду мнений! Обучение, Программирование, IT, Развитие, Разработка, Java, Курсы, Бесплатно, Курсы java, Онлайн-курсы, Бесплатное обучение, Халява, Изучение, Обучение детей, Интересные сайты, Полезные сайты, Создание сайта, Веб-разработка, Гифка, Длиннопост

Java Backend Roadmap

И сделал я их именно такими, какими хотел: в каждом уроке – короткое объяснение, когда использовать технологию, и небольшой пример, отражающий это.

Вот, например, как я объясняю, когда а процессе разработке разработке может возникнуть необходимость создать абстрактный класс:

Я создал полностью бесплатный ресурс с туториалами по Java, покрывающий весь backend-роадмап. Делюсь и жду мнений! Обучение, Программирование, IT, Развитие, Разработка, Java, Курсы, Бесплатно, Курсы java, Онлайн-курсы, Бесплатное обучение, Халява, Изучение, Обучение детей, Интересные сайты, Полезные сайты, Создание сайта, Веб-разработка, Гифка, Длиннопост

Пояснение когда может пригодиться абстрактный класс в Java.

А после – пример, отражающий это (приведен фрагмент, так как целиком он не вместится):

Я создал полностью бесплатный ресурс с туториалами по Java, покрывающий весь backend-роадмап. Делюсь и жду мнений! Обучение, Программирование, IT, Развитие, Разработка, Java, Курсы, Бесплатно, Курсы java, Онлайн-курсы, Бесплатное обучение, Халява, Изучение, Обучение детей, Интересные сайты, Полезные сайты, Создание сайта, Веб-разработка, Гифка, Длиннопост

Пример когда может пригодиться абстрактный класс в Java.

Да, небольшая фишка моих туториалов – комментарии немного объемнее, чем обычно в примерах кода в интернете. Но это просто потому что я считаю, что пояснения прямо в коде помогут лучше понять материал.

Поскольку долго вникать в мобильную разработку я не хотел, решил быстро собрать приложение на FlutterFlow. Примерно за неделю справился и выложил. Выглядело оно так:

Я создал полностью бесплатный ресурс с туториалами по Java, покрывающий весь backend-роадмап. Делюсь и жду мнений! Обучение, Программирование, IT, Развитие, Разработка, Java, Курсы, Бесплатно, Курсы java, Онлайн-курсы, Бесплатное обучение, Халява, Изучение, Обучение детей, Интересные сайты, Полезные сайты, Создание сайта, Веб-разработка, Гифка, Длиннопост

Мое обучающее приложение: Java бекенд от А до Я

Для получения первых отзывов есть два пути: либо реклама, либо бесплатно размещать ссылки на своё приложение на популярных ресурсах. Второй вариант занял бы слишком много времени, поэтому я решил инвестировать в рекламу. К счастью, результаты не заставили себя долго ждать — почти сразу пошли положительные (а часто даже восторженные) отзывы. Вот некоторые из них:

Я создал полностью бесплатный ресурс с туториалами по Java, покрывающий весь backend-роадмап. Делюсь и жду мнений! Обучение, Программирование, IT, Развитие, Разработка, Java, Курсы, Бесплатно, Курсы java, Онлайн-курсы, Бесплатное обучение, Халява, Изучение, Обучение детей, Интересные сайты, Полезные сайты, Создание сайта, Веб-разработка, Гифка, Длиннопост

Отзывы о приложении

Рекламу мне удалось настроить довольно эффективно: стоимость скачивания в среднем была меньше двух рублей, а CTR – хорошим. В общем, было и недорого, и приятно осознавать, что делаю что-то полезное.

Но, к сожалению, счастье длилось недолго. Случился Гугл:

Я создал полностью бесплатный ресурс с туториалами по Java, покрывающий весь backend-роадмап. Делюсь и жду мнений! Обучение, Программирование, IT, Развитие, Разработка, Java, Курсы, Бесплатно, Курсы java, Онлайн-курсы, Бесплатное обучение, Халява, Изучение, Обучение детей, Интересные сайты, Полезные сайты, Создание сайта, Веб-разработка, Гифка, Длиннопост

Печалька :(

В письме написали что-то типа "вы забанены по пунктам 8.3 и 10.3 нашего соглашения и бла-бла-бла... в общем идите н****" :). Разбаниться невозможно. Немного погрустил, конечно, но основной целью было мое обучение, так что пережил. Говорят, такая проблема возникает, если Google находит связанный с твоим аккаунтом ранее заблокированный аккаунт, но я ни разу в жизни не видел другого. Гугл есть Гугл – знаю, что он банит аккаунты пачками просто потому, что "ему что-то показалось", а что именно – не скажет. Вывод: Гугл – зло, ребята :) Что тут еще сказать не знаю.

Через пару лет захотелось снова выложить весь материал, немного его отредактировав, но уже в формате сайта, а не приложения.

Думаю много кому будет полезно, ведь бесплатный, структурированный ресурс покрывающий весь Java-бэкенд найти в интернете наверное не так просто, тем более который глубоко поясняет сложные темы типа:

  • "Зачем нужен Spring Framework и почему он стал настолько прорывным в 2000-х?"

  • "Как Spring работает внутри и какую роль играет DispatcherServlet?"

  • "Абстрактные классы vs Интерфейсы"

  • "Внутренний класс vs Статический класс"

  • "Уровни изоляции транзакций"

  • Различные паттерны проектирования

...и многое другое. Ресурс даже затрагивает DevOps и объясняет Docker – опять же, коротко, ясно и с примерами.

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

На будующее у меня довольно много планов касемо этого проекта, хочу добавить задачи, тесты, возможно некий эмулятор real-time собеседования, хочу добавить целый раздел с разбором типичных задач по HashMap которые есть на любом интервью по Java, также раздел с алгоритмами хочу добавить и многое другое.

В сайт вложено много сил. Дизайн — кастомный. Как видите, старался сделать его современным и приятным. "Modern", как это у нас в русских деревнях говорят 😊. На написание и оформление двухсот уроков на страницах сайта тоже ушло немало времени — нейросетки с такой задачей пока адекватно спарвиться не смогут. В добавок в процессе разработки сайта открывал для себя Next.js, ведь фронтенд сайта построен именно на нём.

Буду очень благодарен за любой тёплый отзыв. Если появятся вопросы — можете смело написать мне через форму или почту на сайте.

Буду рад, если мой проект хоть немного поможет вам на пути к успеху. Желаю всем продуктивной учёбы и крутых карьерных достижений! Пока-пока 👋

Показать полностью 7
[моё] Обучение Программирование IT Развитие Разработка Java Курсы Бесплатно Курсы java Онлайн-курсы Бесплатное обучение Халява Изучение Обучение детей Интересные сайты Полезные сайты Создание сайта Веб-разработка Гифка Длиннопост
139
user10309444
22 дня назад

Java и нейросеть⁠⁠

Назрел такой вопрос. Сейчас нейросеть хорошо пишет код. Ответьте мне честно, есть ли те, кто официально работают и зарабатывают деньги, работая java разработчиком, которые просто просят нейросеть генерировать код и таким образом спокойно работая? То есть практически не прикладываю усилия.

IT Программирование Java Текст
9
511
monobogdan
monobogdan
Посты о ремонте и моддинге ретрогаджетов.
TECHNO BROTHER
22 дня назад

Пишем 3D-игру для ретро-устройств весом в 600Кб…⁠⁠

...которая работает на первых Android-смартфонах в мире, компьютерах из 90-х и даже Mac'ах! Часть 2.

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Иногда у меня лежит душа просто взять и написать какую-нибудь небольшую игрушку с нуля, без использования готовых движков. В процессе разработки я ставлю перед собой интересные задачки: игра должна весить как можно меньше, работать на как можно большем числе платформ и использовать нетипичный для меня архитектурный паттерн. Недавно я начал писать ремейк классических «танчиков» и в рамках серии статей готов рассказать о всех деталях разработки трёхмерной игры с нуля в 2025 году. Если вам интересно узнать, как работают небольшие 3D-демки «под капотом» от написания фреймворка до разработки геймплея — жду вас под катом!

❯ Предисловие

Ещё в начале этого года, мне взбрело в голову проверить насколько концепция «Write once, run anywhere» правдива. Все мы знаем, что Java достаточно обширно используется в Enterprise-секторе по типу банков, Android-гаджетах в качестве языка, на котором написано около 80% системы и даже в смарт-карточках, куда входят привычные нам SIM и банковские карты.

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Изначально я хотел написать игру, которая работала бы не только на самых первых Android-смартфонах в мире, но ещё и на ретро-кнопочных телефонах, и при всём этом была 3D. В течении недели, я успел написать некоторые наработки для трёхмерной гоночки с примитивной физикой на основе «линий»:

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

В игре был мультиреднер для M3G и MascotCapsule... не хуже игр Fishlabs :))

Но затем я понял, что лишаюсь очень многих фич языка. Дело в том, что игры для Java-телефонов писались не столько на самой «джаве», сколько на её своеобразном диалекте. В мире C/C++ такой подход принято называть «C с классами», но в случае Java - подход заключался в написании большей части логики в одном-двух классах для улучшения производительности игры. Наследование, полиморфизм и абстракции на кнопочных телефонах использовать не рекомендуется. Кроме того, версия JDK в кнопочных телефонах была на уровне 1.3 — а значит, никаких дженериков и иных полезных фишек Java.

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Про разработку игр для кнопочных телефонов я писал отдельную статью. Дабы не отвлекать вас от прочтения этой, ссылку оставлю в закрепленном комментарии :)

По итогу я решил сфокусироваться на относительно свежем HTC Dream — первом серийном Android-смартфоне в мире, который вышел в далёком 2008 году с Android 1.0 на борту. В нём используется уже не JVM, а своя виртуальная машина Dalvik с собственным байткодом и версией JDK — 1.5, да и процессор здесь значительно помощнее, а следовательно и куда больше возможностей для разработки!

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Поскольку игру я разрабатываю и отлаживаю на ПК, у меня также есть отдельный билд и для ретро-компьютеров с GPU из 90-х и нулевых. И в рамках статьи, мы, конечно же, сделаем с вами практические тесты!

❯ Рендер

В первой части мы с вами закончили на том, что написали основу для игры — фреймворк, который включает в себя рендерер, менеджер ресурсов на слабых ссылках, некое подобие графа сцены с компонентной системой и загрузчик уровней. Но этого всё ещё мало для 3D-игры и, что самое важное, все эти модули ещё не оптимизированы.

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Например, если грузить уровень «в лоб» и на каждый кубик выделять по отдельному игровому объекту, который «рисует сам себя отдельно» — мы быстро столкнемся с тем, что количество вызовов отрисовки (DIP'ов) превысит все разумные нормы. Для уровня в 16x16 блоков это уже целых 256 DIP'ов - а вкупе с другими танчиками и UI - не менее 260-270.

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Самая базовая оптимизация в таком случае — это отсечение по пирамиде видимости (Frustum culling). Концепция простая: для отрисовки всего, что мы видим с вами на экране используется три матрицы размерности 4x4: мировая (позиция и поворот объекта в мире), вида (камера, позиция из «глаз») и проекции. При перемножении, они образуют так называемую WorldViewProjection-матрицу и если каждую вершину модели умножить на эту матрицу — то мы получаем её позицию в Clip-Space (или NDC) пространстве. Далее растеризатор берёт каждые три трансформированные вершины в качестве углов треугольника и отрисовывает их в рендертаргет - в нашем случае, это экран. Именно за счёт перспективной матрицы проекции и Z-буфера, мы с вами и получаем тот самый эффект трёхмерного пространства.

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

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

public void calculate(Matrix viewProj) {
float[] items = viewProj.Matrix;
planes[0].set(items[3] - items[0], items[7] - items[4], items[11] - items[8], items[15] - items[12]).normalize();
planes[1].set(items[3] + items[0], items[7] + items[4], items[11] + items[8], items[15] + items[12]).normalize();
planes[2].set(items[3] + items[1], items[7] + items[5], items[11] + items[9], items[15] + items[13]).normalize();
planes[3].set(items[3] - items[1], items[7] - items[5], items[11] - items[9], items[15] - items[13]).normalize();
planes[4].set(items[3] - items[2], items[7] - items[6], items[11] - items[10], items[15] - items[14]).normalize();
planes[5].set(items[3] + items[2], items[7] + items[6], items[11] + items[10], items[15] + items[14]).normalize();
}

// Allocation-less
public boolean isPointInFrustum(float x, float y, float z)
{
for(int i = 0; i < planes.length; i++)
{
Plane plane = planes[i];

if ((plane.A * x) + (plane.B * y) + (plane.C * z) + plane.D <= 0)
return false;
}

return true;
}

Далее проверить попадает ли наш кубик или танчик в кадр — дело техники. Есть два подхода: подсчитать Bounding-sphere для модели (радиус относительно самой нижней и самой верхней вершины), или Bounding-box. В самом простом случае, можно обойтись проверкой самой нижней и самой верхней точки Bounding-box'а, однако в некоторых случаях такой алгоритм может давать сбой — например если уткнутся в «стенку» носом в игре:

public boolean isMeshRendererInFrustum(MeshRenderer renderer) {
float x = renderer.Parent.Position.X;
float y = renderer.Parent.Position.Y;
float z = renderer.Parent.Position.Z;
Vector min = renderer.Mesh.BoundingMin;
Vector max = renderer.Mesh.BoundingMax;

return isPointInFrustum(x + min.X, -(y + min.Y), z + min.Z) || isPointInFrustum(x + max.X, -(y + max.Y), z + max.Z);
}

Конкретно в нашем случае, такая оптимизация помогает сэкономить около 100 DIP'ов и даёт неплохой прирост FPS. На Galaxy S3 с Mali 400MP4 мы получаем стабильные 60FPS, в то время как на Xperia Play — около 30... Что-ж, этого всё равно мало, тем более для смартфона, в котором GPU — кровный брат Xenos в Xbox 360...

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Нарисовать 256 кубиков для GPU, даже мобильного — не проблема, особенно если они не бьют по филлрейту. Однако на классических мобильных GPU был строгий бюджет на число DIP'ов — в идеале не более 100, иначе FPS заметно просаживается даже на примитивной геометрии. Поэтому для оптимизации можно использовать технику батчинга: объединяем все кубики с одним материалом в сцене в одну большую модель и рисуем за один вызов DIPUP:

public void bake() {
int uniqueMaterials = 0;

batchList.clear();
batchRenderers.clear();
world.findComponentsOfType(BatchedMeshRenderer.class, batchRenderers);

for(int i = 0; i < batchRenderers.size(); i++) {
BatchedMeshRenderer renderer = batchRenderers.get(i);
renderer.IsTakenByBatcher = false;

if(renderer.Mesh != null && renderer.Material != null) {
if(renderer.Mesh.Buffers.length != 1)
continue; // Only simple meshes is supported now

Batch batch = meshes.get(renderer.Material);

if(batch == null)
meshes.put(renderer.Material, batch = new Batch(renderer.Material));

batch.addMesh(renderer);
}
}

for(Map.Entry<Material, Batch> materialBatch : meshes.entrySet()) {
batchList.add(new BatchHolder(materialBatch.getKey(), materialBatch.getValue()));
materialBatch.getValue().finish(); // Upload mesh to GPU
}
}

После этого, FPS поднимается до очень приятных значений - целых 45! Однако есть и обратная сторона: эта техника очень сильно бьёт не только по памяти, но и в случае динамического батчинга (танки ведь уничтожают кубики) - по процессору. Однако можно и далее оптимизировать этот алгоритм путём разбиения батчей на сетку, чтобы отсекать невидимые группы "кубиков" :)

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Следующая тема — это материалы для поверхностей, описывающие внешний вид модели на экране. В первой статье я написал базовую систему материалов, которая оборачивала в себе набор рендерстейтов и парочку текстур: Diffuse и Detail. Но мало кто помнит, что ещё до шейдеров, в FFP был довольно мощный инструмент, именуемый комбайнерами. По сути, комбайнеры — это возможность задействования сразу нескольких текстурных юнитов для смешивания двух и более текстур за один вызов отрисовки.

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Пример использования комбайнеров — плавное смешивание двух текстур на ландшафте с использованием маски. Эдакая вариация техники Splat mapping

Поэтому я решил написать загрузчик для материалов, описанных в простом текстовом формате по типу ini-файлов. В секции Texture описываются используемые текстуры, которые затем подгружаются из пула ресурсов, в RenderStates — напрямую указаны поля в классе Material, а в Combiners — очень-очень примитивная вариация на тему шейдеров!

[Texture]
Primary = textures/t72_diffuse.tex
Secondary = textures/brick.tex

[RenderStates]
AlphaTest = 0
AlphaTestValue = 1

DepthWrite = 1
DepthTest = 1
AlphaBlend = 0
Fog = 1
Unlit = 1

[Combiners]
Sample Primary
Interpolate Secondary 0.3
MultiplyColor Primary

Изначально я хотел сделать чтобы материалы описывали эдакий набор инструкций как «шейдеры» в Quake 3. Однако учитывая отсутствие лямбд в Java 1.5, реализация на интерфейсах (и тем более на рефлексии) не впечатлила своей производительностью и я решил сделать «программируемыми» только сами комбайнеры. Суть простая: отдельные псевдо-шейдеры реализуют интерфейс FixedFunctionShader и в теле метода onApply применяют необходимые операции над комбайнерами. При этом строго запрещается менять стейт самого графического API кроме биндинга текстур:

static class Sample implements BaseGraphics.FixedFunctionShader {

@override
public void onApply(Material material, int combiner, float[] params) {
if(params.length != 1)
throw new ShaderException(this, material, params, "Expected 1 argument");

int texId = (int)params[0];
Texture2D tex = material.Textures[texId];

if(tex == null)
throw new ShaderException(this, material, params, "Texture " + texId + " was null");

tex.bind();

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0 + combiner);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0 + combiner);

glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
}
}

Затем при вызове отрисовки модели, рендерер выполняет «инструкции» для таких комбайнеров по одному и если нужно — откатывается до простой «однотекстурной» версии (драйвер GLES на Mali-400 и VideoCore IV не поддерживает комбайнеры, несмотря на то, что спецификация требует их поддержки). Получается довольно шустро:

if(GPUClass.QualityLevel >= com.monobogdan.engine.GPUClass.QUALITY_LEVEL_NORMAL) {
for (int i = 0; i < Material.COMBINER_STAGE_COUNT; i++) {
// Reset combiner state
glActiveTexture(GL_TEXTURE0 + i);
glDisable(GL_TEXTURE_2D);
}

for (int i = 0; i < material.Shaders.length; i++) {
Material.ShaderInstance instance = material.Shaders[i];

glActiveTexture(GL_TEXTURE0 + i);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glEnable(GL_TEXTURE_2D);
instance.Shader.onApply(material, i, instance.Params);
}
} else {
// Single texture fallback for very slow GPU's
glActiveTexture(GL_TEXTURE0);
setState(GL_TEXTURE_2D, material.Textures[0] != null);
material.Textures[0].bind();
}

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Наполовину кирпичный танк — видели ли вы когда-нибудь такой камуфляж? :)

Следующая тема — рендеринг текста. В более ранних статьях я обычно не парился над демками и просто рисовал текст нативными средствами системы в текстуру, а затем рисовал полноэкранный квад. Такая методика работает шустро на смартфонах, но очень тормозная на ПК и более того, такая текстура занимает слишком много VRAM! Однако чаще всего я использую так называемые битмапные шрифты, которые состоят из атласа — текстуры с «запеченными» буквами и информации о том, где какой символ в ней находится. Для генерации таких шрифтов я использую утилиту BMFont, а сам код рендеринга получается очень простым:

public void drawString(BitmapFont font, Vector color, float x, float y, String str) {
if(font == null)
throw new NullPointerException("font was null");

if(str == null)
return;

int sz = font.Size / 2;

for(int i = 0; i < str.length(); i++) {
char chr = str.charAt(i);

if(chr == ' ')
x += sz;
else {
BitmapFont.CharacterInfo chrInfo = font.getCharacter(chr);
drawImage(font.Pages[chrInfo.Page], x, y + chrInfo.YOffset, chrInfo.X, chrInfo.Y, chrInfo.Width, chrInfo.Height, chrInfo.Width, chrInfo.Height, color);
x += chrInfo.Width;
}
}
}

И результат - весьма симпатичным:

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

В целом, далее особо оптимизировать и нечего для рендерера. Инстансинга в FFP нет, шейдеров — тоже, а рендер идентичный и на Android, и на ПК. Поэтому имеем что имеем!

❯ Аллокации

Однако когда я начал отлаживать игру на смартфонах, я заметил резкие просадки кадров и абсолютно нестабильный FPS. При этом характер лагов был константный: раз в 2-3 секунды просадка в 20 кадров. Заглянув в logcat, я обнаружил что Dalvik постоянно вызывает GC (сборщик мусора) и блокирует все потоки на невероятные 16мс — даже для простейших объектов в «куче»! В зависимости от устройства, Dalvik выделяет от 8 до 32Мб памяти для каждого приложения - что очень немного!

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

В первой статье я рассказывал о том, что большинство объектов у меня мутабельные и предполагают аллокацию не в update/draw, а в конструкторе компонента. Это касается векторов, матриц и иных примитивных классов для различных расчетов — ведь в отличии от .NET, в Java нет Value-типов, которые можно выделить на стеке, кроме примитивов. Например, если в C# написать такой код для сложения двух векторов:

struct Vector3 {
public float X, Y, Z;

public Vector3(float x, float y, float z)
{
X = x;
Y = y;
Z = z;
}

public static Vector3 operator +(Vector3 a, Vector3 b)
{
return new Vector3(a.X + b.X, a.Y + b.y, a.Z + b.z);
}
}

...

Transform.Position += Velocity;

То из-за того, что Vector3 — простая структура без ссылок на управляемые объекты, которая не требует контроля от GC, рантайм .NET выделит её на стеке, а не в куче и автоматически удалит при выходе из скоупа метода, где она использовалась. Если попытаться сделать такое в Java:

public static Vector3 add(Vector3 a, Vector3 b)
{
return new Vector3(a.X + b.X, a.Y + b.y, a.Z + b.z);
}

...

transform.position = Vector3.add(transform.position, velocity);

То мы получим аллокацию для каждого объекта, вызывающий этот участок кода на каждый кадр. И когда придёт время вызывать GC — он обязательно тормознет игру и вызовет огромные фризы, прямо как в Minecraft на ПК. Главный нюанс здесь в том, что Dalvik оптимизирован под минимальное потребление памяти и поэтому начинает слишком часто вызывать GC, тормозя работу игры. В смартфонах с большим объёмом ОЗУ (хотя-бы 1Гб) таких проблем уже нет.

Но как я уже и сказал выше — мои игровые объекты и компоненты написаны так, чтобы не нагружать ни GC, ни кучу, но сборщик мусора всё равно продолжает тормозить игру, а значит нужно максимально экономить аллокации. Начав профайлить код, я обнаружил что огромное число аллокаций приходится на... итераторы! Да-да, та же самая проблема, что и в примере с векторами: даже несмотря на крошечный вес в памяти, итерации в каждом кадре засоряют хип и по итогу вызывают GC. Решение: перевести все индексированные списки на классический for:

for(int i = 0; i < GameObjects.size(); i++) {
GameObjects.get(i).onUpdate();
}

// Second pass for late updates
for(int i = 0; i < GameObjects.size(); i++)
GameObjects.get(i).onLateUpdate();

И после этого, частота вызова GC наконец-то стабилизировалась!

❯ Ввод

Отдельный вопрос — это грамотная обработка ввода. Хочется чтобы наша игра поддерживала не только клавиатуру, но и геймпады, а на смартфонах — ещё и виртуальные джойстики. Чтобы не размазывать подсистему ввода в игре на 150 источников как в Unity, есть смысл её абстрагировать на некий виртуальный геймпад с необходимыми для игры кнопками: в нашем случае это стрелки и кнопка стрельбы.

Затем необходимо замаппить физические кнопки на наш виртуальный геймпад. Для этого, на смартфонах я сделал таблицу с маппингом, которая подходит для большинства игровых гаджетов: Xperia Play, игровых консолей на Android'е из 2012-го и даже смартфонов с аппаратными QWERTY-клавиатурами. И если захочется добавить возможность переназначения кнопок — это тоже не станет проблемой!

private static int[] xperiaPlayMapping = {
KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT, KeyEvent.KEYCODE_DPAD_CENTER,
KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_BUTTON_X, KeyEvent.KEYCODE_BUTTON_Y, KeyEvent.KEYCODE_BUTTON_R1, KeyEvent.KEYCODE_BUTTON_L1
};

private static int[] genericQWERTYMapping = {
KeyEvent.KEYCODE_A, KeyEvent.KEYCODE_D, KeyEvent.KEYCODE_W, KeyEvent.KEYCODE_S, KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_SPACE, KeyEvent.KEYCODE_J, KeyEvent.KEYCODE_K,
KeyEvent.KEYCODE_Q, KeyEvent.KEYCODE_E
};

public static int[][] ConversionTable = {
xperiaPlayMapping,
genericQWERTYMapping
};

...

private int resolveGamePadTranslationTable(int keyCode) {
for(int i = 0; i < GamePadKeyTable.ConversionTable.length; i++) {
int[] keys = GamePadKeyTable.ConversionTable[i];

for(int j = 0; j < keys.length; j++) {
if(keyCode == keys[j])
return j;
}
}

return -1; // Not resolved
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
int gamePadKey = resolveGamePadTranslationTable(keyCode);
handleKeyEvent(event.getScanCode(), Input.STATE_RELEASED);

if(gamePadKey != -1)
handleGamePadEvent(gamePadKey, Input.STATE_RELEASED);

return true;
}

По итогу, у нас есть унифицированное управление на ПК и смартфонах, покататься в нашей демке можно даже на легендарной Xperia Play!

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Для смартфонов без аппаратной клавиатуры, виртуальный геймпад пишется буквально за 5 минут. Главное — использовать относительные нормализованные координаты для адаптивности и учитывать Aspect Ratio устройства, который может быть разным:

public void drawUI() {
VerticalInput = 0;
HorizontalInput = 0;

float scaled = UI_BASE_SIZE * Scale;
float baseY = 1.0f - (scaled * 3); // 0.7f is base coefficient for 1.0f scaling

if(game.Runtime.UI.imageButton(arrowUp, scaled, baseY, scaled, scaled, true))
VerticalInput = 1;

if(game.Runtime.UI.imageButton(arrowDown, scaled, baseY + (scaled * 2), scaled, scaled, true))
VerticalInput = -1;

if(game.Runtime.UI.imageButton(arrowLeft, 0.0f, baseY + scaled, scaled, scaled, true))
HorizontalInput = -1;

if(game.Runtime.UI.imageButton(arrowRight, scaled * 2, baseY + scaled, scaled, scaled, true))
HorizontalInput = 1;
}

❯ Тестируем игру

Пришло время протестировать то, что мы успели с вами сделать за неделю. И сегодня в тестах участвует сразу несколько машинок: Asus eeePC 4G в роли «компьютера из 90-х», Sony Ericsson Xperia Play, iPhone 4S с нюансом и Samsung Galaxy Y Pro. Все гаджеты по своему хороши, имеют разные GPU и всех их объединяет статус легендарных.

Начинаем с SE Xperia Play 2011 года выпуска, который изначально позиционировался как игровой смартфон. По сути, Xperia Play - чуточку переделанный Xperia Pro, где QWERTY-клавиатуру заменили на геймпад, при этом аппаратная платформа почти всех "сонериков" 2011 года идентичная: чипсет Qualcomm MSM8250 с ARMv7-совместимым ядром Scorpio на частоте 1ГГц и GPU Adreno 205 (ребрендинг ATI Imageon Z430, на архитектуре Xenos), 512Мб ОЗУ типа DDR1 и 512Мб флэш-памяти. С смартфонами в те годы была такая же ситуация, как и с компьютерами в начале нулевых: прогресс был слишком быстрым и уже в 2012 году, Xperia Play не тянул многие свежие игры из-за слабенького процессора и GPU!
Но в нашем случае, он показывает себя неплохо и стабильно тянет рендеринг уровня и танчика в 40-45 FPS... В играх на Unity3D, Adreno 205 таким результатом похвастаться не мог.

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Переходим к iPhone 4S, который, как я уже сказал, с некоторым нюансом: это китайская реплика на Android. При этом довольно интересен тот факт, что у копии очень крутая IPS-матрица почти такого же разрешения (800x480 против 960x640), как и на оригинальном айфоне. Работает "клон" на базе чипсета MediaTek MT6515 2012 года выпуска с одним ядром Cortex-A9, работающим на частоте 1ГГц и GPU PowerVR SGX531 Ultra. Также в смартфоне установлено 256Мб оперативной памяти и 256Мб постоянной - в общем, типичный бюджетник тех лет. GPU от PowerVR - главное достоинство этого смартфона в плане гейминга, наша демка спокойно выдаёт 50-60 стабильных FPS. Я считаю что это прекрасный результат.

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

ERTY-клавиатурой, но и очень диковинным (и родственным Raspberry Pi) процессором Broadcom BCM21553 с одним ARMv6-совместимым ядром на частоте 832МГц и крайне необычным GPU собственной разработки VideoCore IV. Дело в том, что GPU в чипсетах Broadcom выполняет роль системного монитора и по архитектуре заметно отличается от классических видеоускорителей. По сути, это DSP с очень крутым векторным сопроцессором из-за чего его отчасти можно назвать софтрендером. Однако ранние драйвера для этого GPU были очень сырыми из-за чего большинство игр выдавали артефакты или работали очень медленно. Наша игрушка - не исключение, всего лишь 20 FPS при 240x320...

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Переходим к довольно необычной машинке: Asus eeePC 4G. Первые модели легендарной линейки нетбуков отличались очень низкой ценой, довольно слабым и прожорливым процессором Celeron M 353 на архитектуре Dothan (прямой поток Pentium III Tualatin) и частоте 900МГц, встроенной графикой Intel GMA900 с поддержкой пиксельных шейдеров 2.0 и довольно небольшим объёмом ОЗУ в 512Мб типа DDR2. Здесь я проводил тесты на JRE 1.7 - и получил почти 60 FPS... за вычетом того, что раз в 3-4 секунды я получаю микрофризы и нагрузку на процессор в 80%. Однако сама JRE здесь не причём: такая высокая нагрузка связана с тем, что у GPU нет аппаратного вершинного конвейера и поэтому вся трансформация геометрии происходит на процессоре. Такой вот нюанс:

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

❯ Заключение

Вот такая статья о разработке 3D-игры с нуля у нас с вами получилась. Прошлые статьи в этой рубрике я писал в стиле туториала, но в этой я решил рассмотреть конкретные кейсы и архитектурные решения. И может она не настолько простая и понятная, как статья про разработку «самолетиков» или Top-Down стрелялки по зомби, думаю своего читателя она точно нашла! Если вам интересно, с кодом можно ознакомиться на моём Github.

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

А если вам интересна тематика ремонта, моддинга и программирования для гаджетов прошлых лет — подписывайтесь на мой Telegram-канал «Клуб фанатов балдежа», куда я выкладываю бэкстейджи статей, ссылки на новые статьи и видео, а также иногда выкладываю полезные посты и щитпостю. А ролики (не всегда дублирующие статьи) можно найти на моём YouTube канале.

Что думаете о таком формате статей?
Всего голосов:

Очень важно! Разыскиваются девайсы для будущих статей!

Друзья! Для подготовки статей с разработкой самопальных игрушек под необычные устройства, объявляется розыск телефонов и консолей! В 2000-х годах, китайцы часто делали дешевые телефоны с игровым уклоном — обычно у них было подобие геймпада (джойстика) или хотя бы две кнопки с верхней части устройства, выполняющие функцию A/B, а также предустановлены эмуляторы NES/Sega. Фишка в том, что на таких телефонах можно выполнять нативный код и портировать на них новые эмуляторы, чем я и хочу заняться и написать об этом подробную статью и записать видео! Если у вас есть телефон подобного формата и вы готовы его задонатить или продать, пожалуйста напишите мне в Telegram (@monobogdan) или в комментарии. Также интересуют смартфоны-консоли на Android (на рынке РФ точно была Func Much-01), там будет контент чуточку другого формата :)

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

А также я ищу старые (2010-2014) подделки на брендовые смартфоны Samsung, Apple и т. п. Они зачастую работают на весьма интересных чипсетах и поддаются хорошему моддингу, парочку статей уже вышло, но у меня ещё есть идеи по их моддингу! Также может у кого-то остались самые первые смартфоны Xiaomi (серии Mi), Meizu (ещё на Exynos) или телефоны Motorola на Linux (например, EM30, RAZR V8, ROKR Z6, ROKR E2, ROKR E5, ZINE ZN5 и т. п., о них я хотел бы подготовить специальную статью и видео т. к. на самом деле они работали на очень мощных для своих лет процессорах, поддавались серьезному моддингу и были способны запустить даже Quake!). Всем большое спасибо за донаты!

Пишем 3D-игру для ретро-устройств весом в 600Кб… Опрос, Гаджеты, Смартфон, Программирование, Java, 3D, Gamedev, Opengl, Android, Android разработка, Гифка, Длиннопост

Статья написана при поддержке Таймвеб КЛАУД.

Показать полностью 22 1
[моё] Опрос Гаджеты Смартфон Программирование Java 3D Gamedev Opengl Android Android разработка Гифка Длиннопост
42
1
DELETED
25 дней назад

Когда действительно ты кому то нужен⁠⁠

Когда действительно ты кому то нужен
[моё] Картинки Юмор Java Резюме
1
6
DELETED
25 дней назад
Серия 1 часть

Моя работа над собой. Стать "Java разработчиком".Часть 1⁠⁠

Приветствую, дорогие жители Pikabu.ru!
Я инженер-программист станков с ЧПУ. Всю свою взрослую жизнь работаю на металлообрабатывающих предприятиях. Сейчас я пишу управляющие программы для обработки изделий нефтегазовой отрасли.

Когда-то давно, в 2013 году, я пришел на завод учеником оператора станков. Тогда мне казалось, что какие-то потусторонние силы управляют этой машиной. Тяга к развитию в этой сфере росла очень быстро, интерес вызывало буквально любое изделие, которое я делал. Первое время я просто зубрил действия, которые нужно было предпринимать для обработки, так как специфика давалась с трудом. Но всё же получалось у меня всё хорошо.

Через шесть месяцев я стал «оператором станков с ЧПУ». На тот момент я получал неплохие деньги, но со временем ситуация ухудшалась. К 2015 году я уже был женат, и денег совсем не хватало на жизнь. Штат расширялся, приходили новые люди — с опытом и без. Так как я работал по сдельной системе, зарплата была мизерной.

Смотря на всё это, мы с семьёй решили переехать в Казань, так как в нашем городе нас ничего не держало, кроме родителей. На тот момент у меня была Нексия 2004 года, за которую меня всё время «булила» жена =D. Мы загрузили машину всеми своими пожитками и поехали покорять Татарстан.

Ах да, чуть не забыл... Перед выездом мы вообще не знали, куда едем — даже квартиру не арендовали. Единственное, что сделали заранее — посмотрели вакансии, какие есть в городе, и всё.

По приезду мы начали обзванивать арендодателей квартир — денег было очень мало. Даже пришлось сдать всё золото, какое было... После нудных обзвонов и просмотров квартир мы очень сильно устали: ни одна квартира не была пригодна для жилья. Но случилось чудо — под вечер, когда уже смеркалось, мы позвонили по удачному объявлению и нашли квартиру — очень приличную и за небольшие деньги. Квартира, кстати, была на улице Музыкальной. Хозяева оказались хорошими людьми.

На следующий день начали договариваться о собеседованиях. И, к удивлению, быстро нашли работу: я устроился на завод, супруга — в IT-организацию рекрутером.

Казалось бы, при чём тут вообще Java? Когда пойдёт рассказ об этом? Всё по порядку.

Через некоторое время моей супруге предложили должность в новом городе. Так как она занималась подбором IT-специалистов, её рассмотрели как кандидата и пригласили на собеседование в город Иннополис. Мы впервые тогда услышали об этом городе и начали изучать информацию по нему и были приятно удивлены. Сама мысль, что город новый, давала какую-то надежду. Оказалось, город совсем молодой, стройка шла полным ходом. По всей России приглашали IT-спецов с релокацией и разными плюшками. В итоге супругу взяли на работу, и мы переехали.

После переезда я сильно задумался: а там ли я работаю, где хочу? Всю жизнь на заводе? Не, это не про меня. И я начал искать IT-курсы с нуля. Изучая рынок, понял, что самый востребованный язык — это Java. Нашёл курсы молодого бойца Java в КФУ (Казанский (Приволжский) федеральный университет). Учёба сперва пошла довольно плавно, но со временем я заметил, что теряю фокус и не могу сфокусировать себя по полной. Постоянные вопросы самому себе и преподавателям — как это всё работает — не давали никакого результата, я чувствовал, что упёрся в стену, и никто не мог объяснить мне и поставить на путь истинный, дать конкретную базу по программированию. В итоге ничего хорошего не произошло: я потерял веру в себя, был просто полностью опустошён из-за этого. Вдобавок меня ещё и сократили с работы. Начался самый грустный период, в который любая попытка взяться за программирование самостоятельно, даже просто выучить БАЗУ — просто БАЗУ, Карл! — заканчивалась ничем. Не понимая, что происходит, я просто опустил руки и забил на это.

В итоге, не реализовав себя как IT-специалиста, и с текущей работы меня тоже попёрли — мы уехали обратно на родину.

P.S. Если увижу интерес — продолжу дальше свой рассказ.

Показать полностью
[моё] Эмоциональное выгорание Java Учеба Работа ЧПУ Рассказ Программирование Текст
4
17
zinger111
1 месяц назад

Ответ l.smirnov в «Пояснительная бригада: получаем банан»⁠⁠2

Поздравляю, вы написали хуевый код на Джаве )
Никогда такого не было пиздеж, каждый первый спициалист с скиллбокса не даст соврать и вот опять!
Ну все, Джава мертва, старый унылый кусок говна, пора выкидывать, ведь тупой рандом написал на ней говно...


Но давайте, раз уж мы тут ниибать специалисты, подумаем еще 2 минуточки, над этим ниибически ахуительным тезисом "ахахха язык_название_1 полнае гавно".
Попробуем так сказать в анализ, логику, экстраполяцию даже, не побоюсь этого сложного слова.

Можно ли написать говно на ЛЮБОМ языке?
Отвечает эксперт(я): ага, ващще изи. Ну тоесть гдето сложновато, так как некоторые языки и их инструментарий будут упорно препятствовать, но бля - была бы цель!

Хммммм, а можно ли написать красиво на ЛЮБОМ языке?
Опять отвечает иксперт(я): ну, это конечто блять уметь надо, но вообще - да!
Все языки существуют для решения определённых проблем.
Некоторые узкоспециализированны, и красивые решения там требуют таки навыков, понимания области применения, и опыта.
Но - сделать красиво, и местами элегантно - можно на любом языке. Даже (прости госпади) на Руби.

Я уже устал расписывать что тот же JavaScript (над которым ржут тупорылые неумехи более десятка лет, и который конечно нонче более ускоспециализирован чем его, хммм, скажем для простоты терминов "старший брат" TypeScript) можно и "типизировать", и писать надежно, модульно, и даже красиво. БЫЛО БЫ УМЕНИЕ, ДА ЖЕЛАНИЕ. Да и php, второй по цитируемости в шуточкаж долбаебами язык - уже давно умеет и в типизацию, и вообще во все на свете. И позволяет создавать реально красивый код.
Но - поток идиотиков, сравнивающих вот эти пальцы (рдни языки) с жопами (другие языки), не разбирающихся ни в отм ни в другом - он блять неисчерпаем...

А по поводу конкретного примера из поста, на который я отвечаю - мне уже даже лень расписывать НАСКОЛЬКО чувак нихуя не понял ни в Джаве, ни в конкретно этой, простой в принципе иерархии классов, ни блять даже в самом ООП...

К чему я все это (ДА НЕ ПЕЧЕТ У МЕНЯ!11!!)?

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

Вам не стыдно?

Показать полностью
[моё] Программирование IT Программист IT юмор Разработка Javascript Java PHP Мат Ответ на пост Текст
8
1091
l.smirnov
1 месяц назад

Ответ на пост «Пояснительная бригада: получаем банан»⁠⁠2

PHP и Java

PHP, сравни жопу с пальцем!

PHP: жопа это не палец.

Java, сравни жопу с пальцем!

Java: я не знаю, что такое жопа, и что такое палец. Подключите библиотеки классов жопа и палец.

Ок, подключаю!

Java: не могу подключить классы жопа и палец, они наследуют свойства и методы класса "тело", а этот класс не подключен.

Ок, подключаю!

Java: не могу создать классы жопа и палец, подключенный класс "тело" имеет версию эволюции 13.5.3, и не поддерживает классы жопа и палец.

Гуглю, пытаясь понять, чем различаются верси тела 20.3.8 и 20.3.9, и в чем различие женского и мужского тела. Ок, подключаю новую версию класса тело!

Java: чтобы сравнить, создайте объект тело с объектами жопа и палец. Не хватает классов "голова, руки, ноги"!

Гуглю, подключаю голову, руки, ноги.

Java: жопа это палец!

Почему!???!

Java: жопа = объект, палец = объект, соответственно жопа = палец!

Программирование IT Программист IT юмор Разработка Javascript Java PHP Ответ на пост Текст
91
803
stavropol
stavropol
1 месяц назад
IT-юмор

Наконец-то, монитор для джавистов!⁠⁠

Наконец-то, монитор для джавистов! IT юмор, Java, Монитор, Сетап, IT, Программирование, Telegram (ссылка)

IT-юмор для джавистов

Показать полностью 1
IT юмор Java Монитор Сетап IT Программирование Telegram (ссылка)
78
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии