Pull to refresh
1
0
Федоров Руслан @aspcartman

User

Send message
Как думаете, почему котлин не пойдет по пути свифта и не начнет в заранее запланированные даты ломать бэквардс компатабилити с автоматическим транслятором кода? Регулярно раз в год выходил мажорный апдейт, который ломал не только синтаксис, но вообще ABI — т.е старые либы отказывались линковаться.

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

Это позволит решить проблему с похожестью на джаву плюс не оставаться жить с откровенными косяками.
Автор молодец: ) Я тут сделал что-то похожее, но без телеграмма. Я сам заинтересовался историей создания удобного удаленного хранилища. Однако от FUSE пришлось частично отказаться по следующим (субъективным) причинам:

1. Я не вижу ни одного проекта на FUSE, который я мог бы назвать стабильным и шустрым, к сожалению. NTFS-3G яркий тому пример, ведь в его разработку вложено великое множество человекочасов совсем не глупых людей. И, тем не менее, показатели производительности этого решения сильно отстают от других, проприетарных, имплементаций (не основанных на FUSE).

2. Корректная имплементация файловой системы это сложно. Нет, правда. Первая итерация выходит очень быстро, но потом практика показывает, что работы впереди непочатый край.

Возможно я не прав и если это так — буду рад примерам FS.

Можно использовать FUSE для того, чтобы предоставить ОС образ, который она может смонтировать и отформатировать в обычную ФС, имлементация и кеши которой живут в ядре. Такой способ позволяет избежать необходимости имплементировать какое бы то ни было подобие файловой системы и дает возможность сосредоточиться на жонглировании блоками + из коробки fsck и поддержка extended attributes.

Чтобы блоки, которых нужно ждать, не тормозили IO соседей, ОС через fuse отдается не .dmg а .sparsebundle. В моем случае бекендом служит яндекс диск. Сейчас диск в тестовом режиме на 180гб забит исходниками всякого рода, видео и игрушками. Кеш на локальном диске пытается удержаться в заданных пределах (20гб) и в памяти (2гб), LRU. +Readahead в 2 блока. 1блок — 8мб (надо меньше, 1мб делать). Локально данные сжимаются snappy и сохраняются в badger, удаленные блоки сжимаются зипом (8).

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

Почему у нас нет Block device in User SpacE? Ближайшее — nbd, linux-only и в неизвестном состоянии.

Перформанс
image


Не могу плюсовать, карма зло.

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

Доведем идею до абсудра: вот у вас в репозитории есть код приложения. И, например, в коде есть множество не связанных классов\пакетов\не важно. Свой домашний класс для работы с UUID, собственная имплементация json-сериализатора, коими нынче принято бороться со скукой в определенных кругах. И таких вот пакетов, скажем, 20.

А потом возьмем и разобьем все это дело на 21 репозиторий. В первом — основной код, и вот таких вот 20 либ. Чтобы ими пользоваться используется просто местный менеджер зависимостей для вашего ЯП — go mod, cocoapods, npm, cargo, вот эти ребята.

Где конкретно здесь появляются неудобства и дискомфорт? И как они изменяются при изменении количества реп с 1 до 100?
Не обязательно. В некоторых компаниях между сервисами общение происходит по RPC, отличному от http/rest. А их, помимо grpc, великое множество. Просадка имеется не в производительности, а в latency. И это на больших масштабах вполне приемлемая цена за масштабируемость.
Две недели назад начал делать тоже самое, удивляясь, что этого никто еще не сделал, и все UI для докера практически бесполезны, да и заходить в них приходится через браузер (с ума все посходили с этим вебом). Я так понимаю проект был на веб стеке собран, на каком-нибудь electron? Печально, что это единственный сегодня существующий способ. Тем не менее, огромное спасибо за ваши старания, это очень круто! /me пошел выкидывать свое поделие в корзину и наслаждаться свободным временем
Вы ставите общительность в претензию каждому своему собеседнику?

К сожалению, в go это не работает. И не очень ясно хорошо это, или нет. PR'ы и просто предложения разворачиваются на месте, потому что они противоречат религиозным убеждениям core team. Как противоположность — swift. Я не люблю swift, но там, в отличии от go, имеет смысл вкладывать силы и время. Их changelog каждый год впечатляет, и все это делает комюнити. Это круто.
Все правильно говорите. Все, что я хотел, это выразить мнение, что язык вынуждает разработчиков страдать, а предоставляемый им альтернативный вариант, по большей части, не применим. Соответственно остается только хотябы на уровне IDE схлопывать бойлерплейт. Не понимаю, что Вам тут было смешно. Это грустно.

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

func connect(addr string) (*connection, error) {
	con, err := db.Connect(addr)
	if err != nil {
		return nil, err
	}

	err = prepare(con)
	if err != nil {
		con.Close()
		return nil, err
	}

	return con, nil
}


Ошибка в нем следующая: если prepare() вывалится с паникой, коннект утечет (кто сказал, что fd закрывается в файналайзере?). Городить ли defer с recover? Наверное не городить. Месяца через три петух на продакшене хорошо прожарится и наточит клюв.

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

func connect(addr string) *connection {
	con := db.Connect(addr)
	onError con.Close()

	prepare(con)

	return con
}


Не положил в переменную — эквивалентно старой доброй мантре. У всех функций неявное последнее возвращаемое значение — ошибка. onError == defer с проверкой на err != nil. Остается единственный вопрос со стектрейсом, но собственно и все.

Но нет. Мы будем страдать. Спасибо google.
Почему же тогда никто их не использует, наоборот, все радостно пишут эту мантру, и ругают за паники? =)
На обработку ошибок «плевать» в более чем 90% случаев. Случаи обработки конкретных ошибок крайне редки. Как часто вы при попытке вставить что либо в бд проверяете на конкретную ошибку о существовании записи и делаете в таком случае что-то другое? Обычно вы просто чистите за собой, куданибудь вываливаете это в лог и все.

Выпад про синие экраны смерти тут некорректен. Язык действительно тебя заставляет либо как идиоту писать после каждой 1 строчки мантру из 4 строк, либо использовать паники. Но в последнем случае тебя Go-сообщество справедливо закидает заранее подготовленным и свеже-подогретым говном. Вот сидим, пишем эту хреноту, да себя и всех вокруг убеждаем, что это хорошо.
Потому что на 3 строчки полезного кода 12 строк iferr!=nil{returnerr}\n мантры. Это бессмысленная трата времени разработчика на печатание и затем на чтение всего этого бойлерплейта. Если их схлопывать, то хоть как-то это можно читать.
Если вас сильно раздражает проверка на if err!=nil, то в Gogland уже давно впилен мой патч, скрывающий их нафиг. image
Извините за некропостинг, но… «Ключи пути»? Серьезно?
Любопытно. Я не считал, но что-то мне подсказывает, что закон сохранения энергии здесь надо учитывать с одной маленькой оговоркой: усваиваемость и скорость обмена веществ. Я знаю людей, которые едят столько, что в меня не влезло бы, при этом весят 50 и не могут набрать.

Я пил от 3 до 5 литров чистой воды, жрал раз 6 в день, в основном овощи и курица, чаще всего просто брал ролл в subway с курицей-беконом без соусов. В зал ходил три раза в неделю, через день, обычные занятия (одна большая, одна малая группа мышц), только они начинались с 20-40 минут элипса на износ, чтобы сжечь глюкозу в ноль. Ну и чтобы со всего этого не слететь, не отказывал себе, если очень хотелось пиццу или шоколадку и не считал это проколом.

В итоге подтянулся, живот пропал, все как заказывали. Just fucking do it, и получай удовольствие. Все это дело продержалось где-то год, потом стал обратно толстеть, похудел на 8кг, это продержалось пол года, и вот сейчас активно идет дубль три. Почему-то гораздо хуже, чем раньше, но видимо 4 года разницы дают знать, хз.
Блин. Серьезно? Он потерял 28кг за больше чем полгода, не ел и долго ходил, а я на 20 за 1.5 месяца (89->69), и жрал каждые два часа, вкусно. И иногда даже пиццы с конфетками. WTF?
1. Очевидно, с чего взяли? Я сказал, открываем менюшку и делаем констрейнты.
2. Очевидно, с чего взяли? По поводу button — а что это изменит?
3. А вот этого не знал.

И я тоже самое сделал, что вы написали — я весь интерфейс сделал в IB, а цвета по условию должны рождаться из кода, следовательно нужны IBOutlet.

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

Т.е я не согласен с утверждением, что любой разработчик сразу поймет проект по сториборду и частично не согласен, что не поймет код — единственная сторонняя библиотека тут это KeepLayout. Можно открыть их страницу гитхаба и один раз прочитать. Констрейнты везде одинаковые и несут один и тот же смысл. Опять же, в следствии малого обьема получается как-то не серьезно. Мы всетаки разработчики, а не индусы, это наша работа шевелить мозгами. Разница лишь в том, на сколько адекватно то, над чем тебе приходится думать, и на сколько усилия соответствуют получаемому результату. Зашарить маленькую обертку над оригинальным AutoLayout займет совсем ничего, а результат — возможность не вылазить из кода и делать интерфейс быстрее и проще, нежели двигать мышкой.
Смотря в какой плоскости. Если совсем абстрагироваться от IB, то UI относительно текстового интерфейса можно и нужно считать прогрессом в плоскости связанной с UX: в большинстве случаев обычному пользователю гораздо проще как-то интуитивно найти нужную кнопку в панели управления (e.g. windows), нежели какой-то там конфиг файл (e.g. linux). Т.е. новичку, особенно далекому от IT, гораздо проще освоить некое графическое представление интерфейса, нежели текстовое. Однако конфиг файлы до сих пор существуют и повсеместно используются, и как причину такого состояния дел я вижу не лень больших компаний сделать UI для своих продуктов, например баз данных, а тот (для меня) факт, что разработчики — не обычные пользователи и им гораздо проще работать с текстом, кодом, нежели искать заветные галочки в дебрях интерфейса. Да, в общем случае для этого нужно много знать и приходится много гуглить, это сильный минус, который покрывается позднее скоростью выполнения работы и лучшим контролем.

Например, что проще, зайти в панель управления -> установка/удаление программ -> найти в списке нужную, нажать на удалить и появившемся wizard еще пару раз нажать на next (как аналог можно рассмотреть упрощенные пакетные менеджеры убунты), или просто вбить в терминал `sudo pacman -R packetName`? В данной ситуации скорость очевидно за вторым вариантом, а больший контроль проявляется как только вы хотите удалить программу и все ее зависимости, или же хотите наоборот оставить зависимости на месте: в интерфейсе этого просто не выведено в упрощенных пакетных менеджерах (ведь от этого страдает UX, иначе зачем изобретать велосипед и заменять популярный и мощный Synaptic в убунту) и в windows не подразумевается возможным, а через терминал `sudo pacman -Rs packetName`. Контроль в большинстве случаев остается за вторым вариантом (оспорить или доказать это утверждение весьма проблематично, однако мне оно кажется очевидным), а его минусом остается тот факт, что пользователь должен знать, что такое sudo, pacman и аргументы последнего. Однако я не считаю, что в случае с UI работа, которую человек должен затратить на то, чтобы пройти весь путь по интерфейсу до получения желаемого результата равна нулю. Я утверждаю, что программистам проще и быстрее разобраться с консольными интерфейсами и конфиг файлами, нежели искать галочки в интерфейсе, потому что для того, чтобы интерфейс удовлетворял всем «нестандартным» потребностям, с которыми неминуемо сталкиваешься при разработке ПО, его приходится изрядно перегрузить.

Возвращаясь к IB, предлагаю провести аналогию и рассмотреть конкретный пример. Допустим я хочу на экране два прямоугольника размером 100х100 и 50х35, цвет каждого прямоугольника зависит от третьих факторов (например рандом), один в правом верхнем углу, другой слева слева снизу. Первый с учетом margin'ов, второй без. При этом я не хочу, чтобы при недостатке места они пересекались, более того пересекались значения координат их точек: ни одна точка первого прямоугольника не должна быть правее ни одной точки второго, аналогично для вертикали (это упрощение, а не усложнение). Уменьшаться должен, при недостатке места, первый прямоугольник. Экран этот должен быть под UINavigationController и нажатие на любой из этих прямоугольников должно вызывать пуш каких-то других экранов в зависимости от третьих факторов (т.е переход не детерминирован на этапе компиляции). Поехали. В дальнейших рассуждениях подсчет времени, затрачиваемого на каждое действие, оставляю за вами. Все максимально минималистично и просто.

IB:
Находим и перетаскиваем UINavigationController, идем в соответствующую вкладку и назначаем его как стартовый. Аналогично перетаскиваем UIViewController и связываем их. Ищем кастум вью, перетаскиваем два инстанса. Выделяем одну из вьюшек, кликаем по кнопке констрейнтов снизу и выставляем соответствующие констрейнты: фиксированные размеры и отступы друг от друга (с последним может возникнуть проблема, ведь если добавить еще одну вью между ними, то IB будет предлагать выставить отступы именно от нее, а не от нужного прямоугольника, ведь она будет ближайшей, и нужно будет (?) идти во вкладку инспектора и делать это там). Далее создаем segue (один или два? А можно ли сделать segue и не указывать destination?) для каждого прямоугольника, либо же IBAction в контроллере, для чего потребуется переключиться на код. Коль уже переключились, допишем еще IBOutlet'ы в контроллер и свяжем их с вьюшками. Не забудем попросить IB обновить представление вьюшек, чтобы убедиться, что они правильно расставлены.

Далее уже в коде во -viewWillAppear выставляем нужные цвета прямоугольникам через оутлеты, и либо в -prepareForSegue или в методах IBAction дописываем пуш на нужный контроллер. Кажется ничего не забыл.

Code only:
AppDelegate.m, в application:didFinishLoading:
```
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[MyViewController new]];
[window makeKeyAndVisible];
_window = window;
```

В MyViewController.m:
В viewDidLoad:
```
UIView *first = [UIView new];
first.backgroundColor = ...;
[first addGestureRecognizer:[[UITapGestureRecognizer alloc] recogrnizerWithTarget:self selector:@selector(firstTap:)]];
[self.view addSubview:first];
_first = first;

UIView *second = [UIView new];
second.backgroundColor = ...;
[second addGestureRecognizer:[[UITapGestureRecognizer alloc] recogrnizerWithTarget:self selector:@selector(secondTap:)]];
[self.view addSubview:second];
_second = second;
```

В updateConstraints:
```
_first.keepTopMarginInset.equal = 0;
_first.keepRightMarginInset.equal = 0;
[_first keepSize:CGSizeMake(100,100) withPriority:KeepHigh];

_second.keepTopOffsetTo(_first).min = 0
_second.keepLeftOffsetTo(_first).min = 0;
_second.keepBottomInset.equal = 0;
_second.keepLeftInset.equal = 0;
[_second keepSizeTo:CGSizeMake(50,35)];
```

Ну и совершенно аналогично с IB в случае с IBAction код пуша соответствующего экрана. Вы действительно считаете, что вариант с IB сделать быстрее? Этот код можно спокойно печатать даже без подсказок и других инструментов, в частности автоматических import'ов и созданий ivar'ов в AppCode (то, что в xcode писать код тяжело похоже никогда не изменится) и гораздо быстрее, чем двигать мышкой по IB в поисках нужных вещей. А с подсказками, особенно fuzzysearch, когда IDE буквально все пишет за тебя — это делается еще быстрее. Плюс этот код легче поддерживать и менять, ведь все, что происходит, находится перед глазами и не скрыто в панельках IB.

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

Так же вы приравняли расстановку view в коде к безобразию без аргументации. Делегирование к устаревшему подходу (подходу к решению какой конкретно проблемы?) аналогично. Почему, кстати, тогда UITableView все еще на делегатах, а не на блоках? Делегирование до появления блоков использовалось для решения всех проблем обратной связи между обьектами, и не для всех оно подходило. Блоки решили этот вопрос. Использовать блоки для всего и вся такой же моветон, как использовать делегирование аналогичным образом.

Создание предполагается делать в -init у view, а расстановку в -updateConstraints. Никакой вермишели, как раз наоборот: создание и расстановка четко разделены и при этом не так далеко, чтобы приходилось бегать из IB в код и обратно, и при изменении одного менять другое. А логика вся остается в VC и никак не пересекается с созданием и расстановкой вьюшек. Какие конкретно минусы в этом подходе?
Советую KeepLayout. Задача всех этих оберток — предоставить синтаксический сахар и только.

В anchors нужно писать вот так
```
[_myView.bottomAnchor constraintEqualToAnchor:_view.topAnchor constant:8.0].active = YES;
````

в KeepLayout вот так

```
_myView.keepTopInset.equal = 8;
```
если я правильно понял, что делает anchors в этом коде (скорее всего нет :) ).
Красивее и правильней создать отдельную сущность для получения и сортировки, она будет тестируема, да, но это сделает кодовую базу сложнее, чего стоит избегать. Если экран большой и содержит в себе очень много логики — возможно да, имеет смысл озаботиться вопросом. Если приложение security-sensitive и тестирование необходимо — тоже. Нужно лишь понимать, что ничто в этом мире не бесплатно и чем больше в коде движущихся частей, тем труднее с ним работать и иногда лучше придерживаться политики, что твой код после тебя будет поддерживать джуниор, и он должен быть максимально прост для понимания и внесения изменений.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity