Как стать автором
Обновить
1
0

Пользователь

Отправить сообщение
Мы данную проблему решили исключительно серверными средствами. Мы с сервера для каждого пользователя(после авторизации) выдаём дерево путь->[компонент[->компонент]] и права действия над ними FULL/VIEW. Всё что приходит в дереве, отображается в интерфейсе с пришедшими ограничениями. То, что не пришло в списке разрешённых компонентов не загружается в DOM модель.
Да, это требует синхронизации интерфейса и сервера. Но она и так требуется при появлении нового функционала. Вопрос в том, кто инициатор синхронизации: разработчик клиента, который говорит о новых путях и компонентах в приложении или разработчик бекенда, который говорит о новых действиях.
При этом скрытие элементов или запрет действий на интерфейсе не означает, что проверку прав доступа не надо делать на стороне сервера.
В нашей схеме, к каждому компоненту может быть привязано действие, выполнение которого проверяется уже на стороне сервера, об этой части прав доступа интерфейс не знает вообще ни чего, но на стороне бекенда эти сущности синхронизованы.
Простите, кому продавать то?
Сейчас большинство кандидатов заполняет своё резюме вот таким образом
Компания ХХХХ, (срока работы 3,5 года)
Программист
Разработка и поддержание модулей системы.
Технологиии:



И таких резюме более 90%. С авторами таких резюме вообще не понятно что «не так».

1. Или они о себе мегакрутого мнения, что не снисходят до уровня объяснения, чем они занимались на работе 3 года. Типа я весь из себя мачо, буду выбирать что хочу. Но такие до собеседования со мной не доходили.
2. Либо пофигисты, типа «и так сойдёт». Но этим совсем ни чего не интересно. Они приходя, могут показать разный уровень знаний. Но потом не могут задать ни одного интересующего их вопроса по проекту, по условиям работы. Им и так «всё ясно и понятно».

К сожалению у нас очень низкая культура в этом отношении. Я не уверен, что это проблема страны или сообщества.

И на счёт тестового задания. Если при поиске кандидата начального уровня можно в технической беседе понять, уровень компетенций. То для сеньора всё сложнее. Нужно понять не только как человек может декомпозировать задачу, но и то, как эта декомпозиция будет отражена в коде. И есть ещё один момент тестового задания показывает ответственность кандидата. Может ли он выполнить задачу в оговоренные сроки, может ли озвучить преемлемые сроки решения этой задачи.
Когда я искал работу, мне ни когда не было «сложно» выполнить тестовое задание. Обычно адекватное тестовое задание занимает 2-4-6 чистых часов работы. Это не те затраты которых жалко. Если вакансия интересна, то соглашаешься на тестовое задание, если не интересная — отказываешься. При правильном подходе к поиску работы не может «накопиться» десять тестовых заданий.
Ну, тогда Java не ваш язык же!

Ну с чего же вдруг так? На Java есть высокопроизводительные системы. И качественно работают. На JavaOne ребята выступали, которые на Java писали биржевой аггрегатор.
И ни чего. Работало с нужными им временными задержками. Просто готовить надо уметь.
Спасибо. Можно пару вопросов?
Сколько же весят ваши индексы на устройствах?
Привязаны ли они к георгафии пользователя?
Нет. Не правильно. В оригинальной статье не говорилось про стрес вызванный посыланием на несколько букв.

Вот отрывок из текущей статьи.
Чем больше ответственность в профессии, тем больше должна быть стрессоустойчивость.

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

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

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

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

Да, часть стресса может быть из-за того, что тебя отматерили, но потом стресс уже должен возникать из-за того, что ты начинаешь думать, как исправить ситуацию. И у адекватного человека, стресс(в понимании усиленного процесса обдумывания ситуации) из-за решения задачи должен кратно превосходить моральный стресс из-за того, что его послали. При этом так же надо заставить себя подумать, почему же тебя послали, что к этому привело, что так же является стрессом в смысле мыслительной работы головой.
Если бы меня отматерили, то я бы во-первых отсортировал бы «междометия» и выявил бы причину, по которой произошла данная ситуация. Нашёл бы решение для исправления ситуации (возможно два решения, оперативное и стратегическое), после чего я попытался бы отстраниться от причины, и попытался бы понять почему меня именно отматерили (косяк произошёл в «не правильный момент», «косяк произошёл в десятый раз» и т.д.).
Михаил, Вы даже не поняли, что я написал.
Вы сказали, что все горазды подменять понятия через обобщения. И сами сделали обобщение в одном и том же комментарии.
Я вижу, что в холиварах по этой теме народ зарубился, на счёт того, что послать человека на три буквы это стресс, а вот прочитать мануал не является стрессом.
Большинство понимают стресс в усечённом понимании, а именно психологический стресс.
А то, что напряжение мозгов это стрессовая для них работа, не думают. Именно о такого рода стрессе говорил и я и blackisback.
Но все упорно возвращаются к тому, что стресс это исключительно посылание на три буквы.
Меня лично это не проймёт и не станет стрессом.

Если возвращаться, к исходной статье, то посыл был именно в том, что надо давать корректную обратную связь. В первый раз она может быть медовой, а в сотый это может быть и общение в стиле «какого ХХХХ».
Но ни кто почему то не задаётся вопросом, а почему дело дошло до сотого.
Если за короткий промежуток времени дело дошло до сотой обратной связи. То есть несколько вариантов:
1. получатель обратной связи не может её понять ни в какой форме и он не компетентен для задач данного уровня
2. тот кто даёт обратную связь не может найти слова, чтобы сформулировать обратную связь, так, чтобы получатель её понял.
3. Банальный саботаж.
4. что-то ещё…

И это прозрачный намёк, что надо что-то менять, если работник не растёт над уровнем задач.
Интересно, почему людям так нравится подменять понятия через обобщение...

Вот уж точно
> Херачишь в зале -> подвергаешь мышцы стрессу
> тренер будет вас на 3 буквы посылать? Это стресс же? Стресс.
Это мой коммент, просто первый раз меня почему авторизовало под неправильной учёткой.
Да вы что? Вы заметили фразу "всё время". Чтобы не раскрывать карты. Представьте, что вы ищите java-программиста и спрашиваете:
«как устроена строка»?
«сколько байт в типе char»?
Если человек претендующий на должность Senior Java Developer полезит за такими вопросами в Google. То для меня это некомпетентность.
А вопросы были именно такого плана.

Так исходная фраза звучит
Т.е. стресс — это плохо вообще-то
. Где здесь про разные оттенки стресса. Да я понимаю, что стресс он не должен быть постоянный. И более развёрнуто на счёт того, что я имел в виду написал ниже blackisback
У нас уже был использован Thrift для межмодульного взаимодействия. Не хотелось вводить ещё один язык.
Плюс не всегда «слабое развитие» это критический минус. Если продукт решает свои проблемы, и ты не планируешь использовать неподдерживаемые фичи. То это не является критическим местом.
Выбирая из пары развивающихся продуктов, которые только выходят на рынок, тут я соглашусь, что надо смотреть на динамику развития.

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

Не знаю, что уважаемый creker подразумевал, что весь транспорт и обвязка пишется руками. Если то, что приходится писать свой сервлет, для работы через http протокол. Или поднимать ручками сервер для работы на сокетах
@Component
class ThriftAdsServer @Autowired constructor(
		@Value("\${thrift.server.port}")
		private val serverPort: Int,
		handler: AdsService.Iface) {

	companion object {
		private val logger = LoggerFactory.getLogger("THRIFT-SERVER")
	}


	private val server: TServer

	@PostConstruct
	fun startServer() {
		logger.info("Thrift server starting at port $serverPort")
		thread(start = true) {
			try {
				val serverTransport = TNonblockingServerSocket(serverPort)
				server = THsHaServer(THsHaServer.Args(serverTransport).processor(AdsService.Processor(handler)))
				server.serve()
			} catch (e: Throwable) {
				logger.error("Server was crashed.", e)
			}
		}
	}

	@PreDestroy
	fun stopServer() {
		logger.info("Try to stop thrift server serving at port $serverPort")
		if (server.isServing) {
			server.stop()
			logger.info("thrift server was stopped")
		} else {
			logger.info("Server wasn't started")
		}
	}

}

То по мне это не большая проблема: написать 40-50 строчек кода для одного сервиса.
Проблема не столько в том, какой набор адаптеров мы выбрали, а в том, что возникают проблемы с синхронизацией серверного и клиентского представления API. Чтобы поддерживать возможность работы команд бекенда и фронтенда независимо друг от друга.
Мы mirage и используем. Дело в том, что при таком подходе для изменения API ты должен вносить несвязанные изменения и на стороне клиента и на стороне сервера. В итоге конфигурация для mirage разрослась. Плюс, как я писал некоторые разработчики меняя модель данных на сервере не всегда меняли модель данных на мираже. Т.е. у нас в mirage есть представление списка сущностей. Список из 20 — 30 записей. И добавление одного поля в данный список приносило много боли.
Когда модель состоит из десятка сущностей — это не очень проблемно, когда количество сущностей кратно возрастает, то возрастает и стоимость «ревью».
Если можно убрать момент «ревью»API, то лучше его убрать.

Писать тесты для выявления ошибок API, это опять вопрос синхронизации. Как можно защититься от того, что разработчик напишет тест только для бекенда, а для «фронтенда» забудет?

Сейчас же с выносом API в единое место, у нас есть гарантия на уровне компиляции, что модели для сервера и клиента будут согласованы. Т.е. во время сборки проекта будет подложена последняя версия API. До этого гарантией служили «соглашения».
Ради интереса на маленьком проекте решил провести небольшой эксперимент.
Изначально на этом проекте тесты написаны над HashMap (эмуляция БД). Т.к. это маленький микросервис, то сложных операций нет: сохранить в таблицу с автоинкрементом, поиск по одному/двум полям. Тесты генерируют малое количество данных, так что такой подход вполне корректен :)
Итак есть отдельный maven модуль, в котором только тесты. Вся бизнес логика в других модулях. Компилирование бизнес-логики в текущих расчётах не учитывается.
В модуле dao объявлено два liqubase changeSet. Добавление таблицы и добавление новых полей в таблицу(эти скрипты естественно не запускаются, если работаю над HashMap).
Есть 5 классов с тестами. Первый класс с пустым тестом, для инициализации SpringContext. В остальных 4х классах 20 тестов. Для каждого варианта делал три запуска тестов. Перед запуском тестов делал mvn clean. Время выполнение брал из логов maven.

HashMap:
— Инициализация: 4.7s
— Тесты: 1.8s
— Maven package: 20.5s

HSQLDB (memory):
— Инициализация: 10.7s
— Тесты: 2.7s
— Maven package: 29.8s

Postgres (in docker):
— Инициализация: 9,9s
— Тесты: 3,1s
— Maven package: 26,9s

Сравнивал, но это было давно, и, естественно, не в пользу postgres.
EmbendedPostgres замедляет работу. Он создаёт новый инстанс на старт нового SpringContext (с запуском всех скриптов обновления). В той же статье, о которой я упомянул было написано, что ребята научились поднимать один инстанс на всю сессию тестов вне зависимости от того, сколько запуститься Spring Context-ов.
Именно по этому мы постепенно мигрируем на «локальные» БД. Это и единичный запуск скриптов обновления или вообще его отсутствие и возможность глазами посмотреть данные в БД. И возможность проверить, как произойдёт накат изменений на существующую структуру данных.
На сервере сборок поднимается Docker-контейнер с Postgres, который потом удаляется тем самым «очищая» результаты работы тестов.

Если Postgres начнёт тормозить, то всегда можно будет настроить RamDisk.
Абсолютно согласен с утверждением.

Но если речь про интеграционные тесты, то тут как раз надо проверять интеграцию :) и моменты с БД скрывают не очевидные подводные камни.
Я выше описал, как мы стараемся решать часть проблем с уровнем БД в интеграционных тестах.
Это другого уровня тесты.
1. В современных движках разработки UI есть свои тесты, включая проверку работы компонентов. Это отдельная тема.
2. Тесты на производительность не запускаются один раз. Т.к. производительность, это не одна операция в единицу секунды. А 10^x операций в течении определённого периода времени.
Test
public void getProduct_twoProductsInDb_correctProductReturned() {
Product product1 = product(«product1»).build();
Product product2 = product(«product2»).build();
productRepository.save(product1);
productRepository.save(product2);

Product result = productController.getProduct(product1.getId());

assertEquals(«product1», result.getName());
}

Очень стрёмный тест, если честно. Если предположить, что в БД есть ограничение на длину строки = 3 символам, то тест может отрабатывать корректно, за счёт кэширования данных на уровне ORM, а вот в реальности результат работы может быть другой.
При повседневной работе над своим текущим проектом я вообще не использую реальной базы: все проверяется на h2

Не помню, какое время назад, примерно год-полтора назад. Была статья на эту тему.
Смысл её был в том, что на проде нашли странную ошибку, которая на тестах не вылезала. Т.е. код отрабатывал одинаково, но вот результаты работы были разными. Оказалось, что ошибка закралась в разном алгоритме работы H2 и Postgres.
В итоге все тесты переписали на Postgres и нашли ещё несколько неочевидных ошибок.
В общем, использования H2 нормально, но может приводить к скрытым ошибкам.
В наших проектах мы используем несколько подходов.
1. Embended Postgres. Разработчику не надо заморачиваться с поднятием БД.
2. Предварительный запуск БД в контейнере. Данный вариант позволяет собрать некоторую «эталонную» версию БД, чтобы не тратить время на создание структуры и прогон всех UPDATE скриптов.

Плюс мы приняли решение, что один тест должен уметь запускаться на одном контексте два раза. Т.е. мы знаем правила нашей системы и делаем формируем объекты с учётом этих правил. На пример, у нас есть «идентифицирующие» поля, это далеко не всегда ID. И такие поля у нас генерируются с учётом timestamp, что позволяет нам не беспокоиться об очистке контекста и отката транзакций.
Пока нет. Это не является в данный момент серьёзной проблемой, чтобы сейчас перестраивать весь процесс разработки.
Я прочитал несколько ваших статей. Достаточно интересно.
Как раз сейчас решаю подобные проблемы. Но у меня задача сложнее:
есть несколько доккер модулей для одного приложения. Каждый из таких модулей живёт в своём репозитории и собирается отдельной сборкой. Хочется настроить режим превью разработки (он же staging). А проблема заключается в том, что есть задачи, которые задевают несколько модулей. И задача состоит в том, чтобы для тех модулей, которые не были затронуты, надо собрать/развернуть из ветки «current» (условно стабильной), а для тех модулей, которые задействованы в изменениях, надо собрать из FEATURE ветки, а после этого установить.
Интересно, можно ли организовать такой pipeline в GitLib?
Нет, такой задачи передо мной не стояло. Я использую Berkley для простых, не связанных данных.
К тому же это очень древняя версия библиотеки. Более новую с открытой лицензией я не смог найти.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность