Что такое файловые ссылки в Linux
Что проверяют
Знаете ли вы, что имя файла и сам файл это разные сущности, и умеете ли выбрать между жёсткой и символической ссылкой. Для разработчика на Go вопрос прикладной: ссылки торчат сразу из нескольких мест стандартной библиотеки, и путаница даёт баги при обходе каталогов и при выкладке.
Как отвечать
Жёсткая ссылка это ещё одно имя того же inode внутри одной файловой системы. Имена равноправны, никакого «оригинала» среди них нет, у inode есть счётчик имён, и данные освобождаются, когда счётчик обнулился и файл никем не открыт. На каталог жёсткую ссылку не создать, через границу файловой системы тоже.
Символическая ссылка это отдельный маленький файл, внутри которого записан путь. Она указывает на каталог, на другую файловую систему и даже на несуществующий путь, и тогда она просто битая. Относительный путь внутри неё разворачивается от каталога самой ссылки, а не от текущего каталога процесса.
В Go это os.Link и os.Symlink, а разница чувствуется в выборе функции: os.Stat идёт по ссылке и описывает цель, os.Lstat описывает саму ссылку. filepath.WalkDir по символическим ссылкам не спускается, распутать цепочку целиком помогает filepath.EvalSymlinks.
Где спотыкаются
Отвечают «удалили оригинал, ссылка сломалась», не разделяя типы. У жёсткой ссылки ломаться нечему, данные живут, пока живо хотя бы одно имя; у символической ломается ровно это.
Обходят дерево через os.Stat и зацикливаются на ссылке, указывающей на родительский каталог. Тип записи берут только из os.Lstat, иначе ссылка неотличима от настоящего каталога.
Переключают символическую ссылку на новую версию удалением и созданием заново. Между двумя вызовами пути не существует, и запрос в эту щель получает ошибку: замена делается созданием временной ссылки и os.Rename поверх, это атомарно.