> Что такое файловые ссылки в Linux (Go)

Уровень: junior · Роль: backend · Язык: Go · Категория: Технические вопросы

Компании: YADRO

Стек: Go

> Пример ответа

Короткий ответ

Файловые ссылки в Linux - это специальные записи в файловой системе, которые указывают на другой файл. Есть два типа: жёсткие ссылки (hard links) - несколько имён для одного inode, и символические (symlinks) - отдельный файл, содержащий путь к цели. Жёсткие ссылки работают только в пределах одной файловой системы и не могут ссылаться на директории, а симлинки лишены этих ограничений.

Подробное объяснение

В Linux файл - это не имя, а inode (структура, хранящая метаданные и блоки данных). Имя файла - это запись в директории, связывающая имя с inode. Жёсткая ссылка создаёт ещё одну такую запись, увеличивая счётчик ссылок в inode. Файл удаляется только когда счётчик становится нулевым.

Символическая ссылка - это отдельный файл типа l, содержимое которого - путь к другому файлу. При обращении ядро подставляет этот путь. Если цель удалена, симлинк становится "битым" (dangling), но сам остаётся.

Ключевые различия:

  • Жёсткая ссылка неотличима от оригинального имени - это просто другое имя того же inode. Симлинк - самостоятельный объект.
  • Жёсткая ссылка не может указывать на директорию (защита от циклов). Симлинк может.
  • Жёсткая ссылка не работает между файловыми системами (inode уникален в пределах одной ФС). Симлинк хранит путь, поэтому работает.
  • При удалении оригинального имени жёсткая ссылка продолжает работать. При удалении цели симлинк ломается.
  • ls -l показывает счётчик ссылок для жёстких, и -> для симлинков.

На практике

Для Go-разработчика знание ссылок важно при работе с файловыми операциями, особенно в контексте контейнеров, CI/CD и управления артефактами.

  • os.Symlink(target, link) - создание симлинка в Go.
  • os.Link(oldname, newname) - создание жёсткой ссылки.
  • os.Readlink(name) - чтение цели симлинка.
  • os.Lstat - получение информации о самой ссылке, а не о цели (в отличие от os.Stat).
  • При сканировании директорий нужно быть осторожным с симлинками - они могут создавать циклы или выходить за пределы ожидаемой области.

Пример кода

GO
package main
import (
"fmt"
"os"
)
func main() {
// создаём файл
os.WriteFile("original.txt", []byte("hello"), 0644)
// жёсткая ссылка
err := os.Link("original.txt", "hard.txt")
if err != nil {
fmt.Println("hard link error:", err)
}
// символическая ссылка
err = os.Symlink("original.txt", "soft.txt")
if err != nil {
fmt.Println("symlink error:", err)
}
// проверяем через Lstat
fi, _ := os.Lstat("soft.txt")
fmt.Println("soft is symlink:", fi.Mode()&os.ModeSymlink != 0)
fi, _ = os.Lstat("hard.txt")
fmt.Println("hard is symlink:", fi.Mode()&os.ModeSymlink != 0)
// читаем цель симлинка
target, _ := os.Readlink("soft.txt")
fmt.Println("target:", target)
// удаляем оригинал
os.Remove("original.txt")
// hard.txt всё ещё работает
data, _ := os.ReadFile("hard.txt")
fmt.Println("hard content:", string(data))
// soft.txt сломан
_, err = os.ReadFile("soft.txt")
fmt.Println("soft error:", err)
}

Как отвечать на собеседовании

Начни с определения, затем сразу переходи к различиям. Приведи пример из практики: почему в Docker-образах симлинки используются для /usr/bin и почему жёсткие ссылки удобны для бэкапов (например, rsync --link-dest). Если спросят про Go - упомяни os.Lstat и os.Readlink, и что os.Stat следует за симлинком. Не углубляйся в теорию inode, если не просят. Держи ответ структурированным: определение → типы → различия → практика.

Что проверяет интервьюер

Интервьюер проверяет:

  • понимание базовой модели файловой системы (inode, директория как таблица имён);
  • умение различать жёсткие и символические ссылки, включая ограничения (ФС, директории);
  • знание поведения при удалении цели;
  • практический опыт работы с файлами в Linux, включая Go-специфику (Lstat vs Stat).

Типичные ошибки

  • Путаница между жёсткой ссылкой и копией файла - копия создаёт новый inode, ссылка - нет.
  • Утверждение, что жёсткая ссылка "указывает на файл" - она указывает на inode, а не на имя.
  • Забывают, что жёсткие ссылки не работают между файловыми системами.
  • Считают, что удаление оригинального имени ломает жёсткую ссылку - это не так.
  • Не различают os.Stat (следует за симлинком) и os.Lstat (смотрит на саму ссылку) в Go.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью