Pull to refresh
42
0
Александр @Lucyfer

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

Send message

если не нравятся if err != nil, а вместо этого хочется исключения (или что-то похожее на исключения), то код бизнес-логики можно преобразовать в continuation-passing style

// логика в виде матрёшки
func example_CPS() {
	userId := 100500
	onError := func(err error) {
		log.Fatal(err)
	}

	readFromDb_CPS(
		userId, 
		func(u *User) {
			processUser_CPS(
				u, 
				func(u *User) {
					saveToDb_CPS(u, func(*User) { log.Println("saved") }, onError)
				}, 
				onError,
			)
		}, 
		onError,
	)
}

// или немножко в арабском стиле: продолжения определяем задом наперед
func example_CPS_inversed() {
	userId := 100500
	onError := func(err error) {
		log.Fatal(err)
	}

	processUserCont := func(user *User) {
		saveToDb_CPS(user, func(*User) { log.Println("saved") }, onError)
	}

	readFromDbCont := func(user *User) {
		processUser_CPS(user, processUserCont, onError)
	}

	readFromDb_CPS(userId, readFromDbCont, onError)
}
Hidden text
func readFromDb_CPS(id int, onSuccess func(*User), onError func(error)) {
	if some_db_error {
		onError(errors.New("not found"))
	} else {
		onSuccess(&User{})
	}
}

func processUser_CPS(user *User, onSuccess func(*User), onError func(error)) {
	if user == nil {
		onError(errors.New("user is nil"))
	} else {
		onSuccess(user)
	}
}

func saveToDb_CPS(user *User, onSuccess func(u *User), onError func(error)) {
	if user == nil {
		onError(errors.New("user is nil"))
	} else {
		onSuccess(user)
	}
}

Для Java есть библиотека мутационного тестирования http://pitest.org/
Суть в том что с помощью инструментирования байткода по определенным правилам (например инвертирование условия в операторе if, замена тела метода на return null и т.д.) изменяется тестируемая система и если при этом не падает ни один тест, то их явно недостаточно. После прогона тесткейса на всех мутациях будет собран настоящий честный code coverage
Для 99.99% ситуаций модель распараллеливания стримов с разворачиванием fork-join пула — явный overkill.

Новый ForkJoinPool теперь использует work-stealing планировщик и рандомизованные очереди, что по некоторым замерам увеличило производительность более чем в 10 раз.
Не совсем про реализацию, но читал в свое время «LINQ in Action». И MSDN, конечно.
Квацитирование — преобразование выражения в ExpressionTree. Попробуйте без этой плюшки сгенерировать, например, SQL-запрос из from p in persons where p.Name == "John" select p;
Как минимум замыкания и цитирование. Допустим, первое как-то поддержено в Java, но второго даже нет в планах.
Еще можно посчитать доработку парсера под linq-запросы.
Это далеко не LINQ — ничего не было интегрировано в язык, т.е. это чисто библиотечная функциональность.
Суть стримов раскрывается в цитате из javadoc:
A sequence of elements supporting sequential and parallel bulk operations. Streams support lazy transformative operations (transforming a stream to another stream) such as filter and map, and consuming operations, such as forEach, findFirst, and iterator. Once an operation has been performed on a stream, it is considered consumed and no longer usable for other operations.

For sequential stream pipelines, all operations are performed respecting in the encounter order of the source, if the source has a defined encounter order. For parallel stream pipelines, unless otherwise specified, intermediate stream operations preserve the encounter order of the source, and terminal operations respect the encounter order of the source, if the source has an encounter order.
Ничто не мешает написать
list.getStream().filter((Person f) -> f.getAge() > 21)
В Spring это более-менее просто реализуется:
Скрытый текст
// допустим храним в памяти
interface SomeInMemoryStorage {
    Collection<Principal> getActivePrincipals();
    void connectPrincipal(Principal principal);
    void disconnectPrincipal(Principal principal);
}

// какой-то storage
@Service
class SomeInMemoryStorageImpl implements SomeInMemoryStorage {

    @Override
    public void connectPrincipal(Principal principal) {
        // восстанавливаем предыдущее состояние
    }

    @Override
    public Collection<Principal> getActivePrincipals() {
        return new ArrayList<>(0);
    }

    @Override
    public void disconnectPrincipal(Principal principal) {
        // можем сохранить состояние
    }
}

public class LifecycleStompWebSocketHandler extends StompWebSocketHandler {

    private static final Log logger = LogFactory.getLog(LifecycleStompWebSocketHandler.class);

    private SomeInMemoryStorage someInMemoryStorage;

    public LifecycleStompWebSocketHandler(SomeInMemoryStorage storage, MessageChannel dispatchChannel) {
        super(dispatchChannel);
        this.someInMemoryStorage = storage;
    }

    // переопределяем пару методов

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        super.afterConnectionClosed(session, status);

        logger.debug("Principal disconnected: " + session.getPrincipal().getName());
        someInMemoryStorage.connectPrincipal(session.getPrincipal());
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        super.afterConnectionEstablished(session);

        logger.debug("Principal connected: " + session.getPrincipal().getName());
        someInMemoryStorage.disconnectPrincipal(session.getPrincipal());
    }
}
«Не стреляйте в пианиста — он играет как умеет»
Смысл статьи — всего лишь дать пару советов Java-newbie.
В .NET куче вместо молодого и старого поколений, есть поколения 0, 1 и 2.

Не только new, young, old. Еще eden, tenured, perm gen, survivor spaces.
Согласен. Сам достаточно много времени провел за чтением JavaDoc и исходников.
К сожалению не сталкивался с VCS-плагинами. Возможно стоит посмотреть как это реализовано в git или mercurial плагинах (исходный код есть на гитхабе).
Про PSI обязательно будет, это, как ни крути, одна из ключевых особенностей IDEA.
Насчет навигации — не понятно между какими именно компонентами?
Народу привычны они,
Законы богов первозданных

Но ведь олимпийские боги — третье поколение.

Information

Rating
Does not participate
Location
Барнаул, Алтайский край, Россия
Registered
Activity