Под капотом может происходить множественное выделение памяти, особенно при частых склеиваниях.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Это версии протокола HTTP, каждая из которых имеет свои особенности и улучшения по сравнению с предыдущими версиями. Важные различия между этими версиями включают следующие аспекты:
Поддерживает одновременное открытие нескольких TCP соединений (обычно 6-8), что позволяет загружать несколько ресурсов параллельно. Однако каждое соединение может обрабатывать только один запрос за раз, что приводит к задержкам из-за блокировки очереди (head-of-line blocking).
Вводит мультиплексирование, позволяющее отправлять множество запросов и ответов асинхронно через одно единственное TCP соединение. Это значительно уменьшает задержки и улучшает производительность при загрузке страниц с большим количеством ресурсов.
Является текстовым протоколом, что означает, что запросы и ответы форматируются в виде читаемого текста.
Бинарный протокол, который делает передачу данных более эффективной и менее подверженной ошибкам в синтаксическом анализе. Бинарный формат упрощает реализацию парсеров и уменьшает размер передаваемых данных.
Заголовки передаются без сжатия, что может привести к значительному объему передаваемых данных, особенно если одни и те же заголовки отправляются повторно с каждым запросом.
Использует механизм сжатия заголовков HPACK, который уменьшает избыточность заголовков, сжимая их перед отправкой. Это особенно эффективно для повторяющихся запросов к одним и тем же серверам.
Не поддерживает приоритизацию запросов, из-за чего браузеры должны использовать эвристики для управления приоритетами ресурсов.
Поддерживает явную приоритизацию запросов, позволяя клиенту указывать приоритет обработки ресурсов, что делает загрузку страниц более эффективной.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Foreign key (внешний ключ) — это ограничение в базе данных, обеспечивающее связь между таблицами и целостность данных.
Он:
- Предотвращает вставку «висячих» записей (без связанных данных).
- Позволяет БД контролировать каскадное удаление/обновление.
- Делает структуру БД более безопасной и логичной.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2💊1
В Go пустой интерфейс
interface{} является особым типом, который может содержать значение любого типа. Это связано с тем, что в Go любой тип реализует пустой интерфейс, поскольку в нем нет методов, которые нужно реализовать. Поскольку пустой интерфейс не требует реализации каких-либо методов, любой тип в Go автоматически реализует этот интерфейс. Это делает пустой интерфейс универсальным контейнером для значений любых типов.
type interface{} interface {}Типа конкретного значения
Самого значения
Когда значение присваивается переменной типа интерфейс, Go сохраняет информацию о типе и значении этого значения. Для пустого интерфейса эта информация может быть любого типа.
Когда значение из пустого интерфейса приводится к конкретному типу, происходит проверка типа во время выполнения. Если значение внутри интерфейса действительно является указанным типом, приведение успешно. В противном случае приведение не удается, и возвращается значение
nil или происходит паника, если приведение выполнено без проверки.Присваивание значений пустому интерфейсу
package main
import "fmt"
func main() {
var i interface{}
i = 42
fmt.Println(i) // 42
i = "hello"
fmt.Println(i) // hello
}
Утверждение типа (Type Assertion)
package main
import "fmt"
func main() {
var i interface{} = "hello"
// Утверждение типа с проверкой
s, ok := i.(string)
if ok {
fmt.Println("String:", s)
} else {
fmt.Println("Not a string")
}
// Утверждение типа без проверки
// Это вызовет панику, если тип не соответствует
s = i.(string)
fmt.Println("String:", s)
}
Использование switch для проверки типа
package main
import "fmt"
func printType(i interface{}) {
switch v := i.(type) {
case string:
fmt.Println("String:", v)
case int:
fmt.Println("Integer:", v)
case bool:
fmt.Println("Boolean:", v)
default:
fmt.Printf("Unknown type: %T\n", v)
}
}
func main() {
printType("hello")
printType(42)
printType(true)
printType(3.14)
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
len и capacity в слайсе Go? 2. capacity: общая ёмкость слайса, включая длину и свободное пространство, доступное для добавления новых элементов
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Это предопределенное идентификатор, используемое для создания последовательностей целочисленных констант. Он применяется в контексте объявления констант и автоматически инкрементируется на единицу с каждым новым значением. Обычно используется для определения множества связанных констант без необходимости вручную назначать каждому элементу значение.
Начинает счет с 0 в каждой новой группе констант.
Каждое последующее использование
iota в одной группе констант увеличивает его значение на 1.При каждом новом объявлении константного блока
iota сбрасывается до 0.package main
import "fmt"
const (
A = iota // 0
B // 1
C // 2
)
func main() {
fmt.Println(A) // Вывод: 0
fmt.Println(B) // Вывод: 1
fmt.Println(C) // Вывод: 2
}
Использование его для создания битовых флагов
package main
import "fmt"
const (
Flag1 = 1 << iota // 1 << 0 = 1
Flag2 // 1 << 1 = 2
Flag3 // 1 << 2 = 4
Flag4 // 1 << 3 = 8
)
func main() {
fmt.Println(Flag1) // Вывод: 1
fmt.Println(Flag2) // Вывод: 2
fmt.Println(Flag3) // Вывод: 4
fmt.Println(Flag4) // Вывод: 8
}
Сброс его в новом блоке
package main
import "fmt"
const (
X = iota // 0
Y // 1
)
const (
Z = iota // 0 (новый блок констант, iota сбрасывается)
W // 1
)
func main() {
fmt.Println(X) // Вывод: 0
fmt.Println(Y) // Вывод: 1
fmt.Println(Z) // Вывод: 0
fmt.Println(W) // Вывод: 1
}
Можно использовать в выражениях и совместно с другими константами для создания более сложных последовательностей.
package main
import "fmt"
const (
_ = iota // пропускаем 0
KB = 1 << (10 * iota) // 1 << 10 = 1024
MB // 1 << 20 = 1048576
GB // 1 << 30 = 1073741824
)
func main() {
fmt.Println("KB:", KB) // Вывод: KB: 1024
fmt.Println("MB:", MB) // Вывод: MB: 1048576
fmt.Println("GB:", GB) // Вывод: GB: 1073741824
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
Линтеры — это инструменты для автоматической проверки кода на ошибки, потенциальные баги и несоответствие стилю кодирования.
В Go есть несколько популярных линтеров:
golangci-lint – самый мощный и популярный, объединяет множество линтеров. go vet – стандартный инструмент для поиска ошибок. golint – проверяет стиль кода (но устарел). staticcheck – анализирует код на ошибки и неэффективность. Устанавливаем
golangci-lint (лучший вариант) go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
После установки проверьте версию:
golangci-lint --version
Запустить проверку в проекте можно так:
golangci-lint run
Можно проверить только определённый файл:
golangci-lint run myfile.go
Если хотите автоматически исправлять ошибки, используйте:
golangci-lint run --fix
Go уже имеет встроенный линтер
go vet ./...
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
В Go функция может возвращать несколько значений одновременно, благодаря множественному возврату.
Ограничений по количеству возвратов формально нет (можно вернуть хоть 10 переменных), но по стилю рекомендуется не перегружать сигнатуру — до 2–3 значений максимум, особенно если не используются именованные возвращаемые значения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤔1
В языке Go отсутствует традиционное наследование. Вместо этого он использует композицию и интерфейсы для достижения полиморфизма и повторного использования кода. Рассмотрим, как это работает.
Позволяет включать одну структуру в другую, что дает возможность использовать методы встроенной структуры. Это часто называют "встраиванием" или "композицией" вместо наследования.
package main
import "fmt"
// Определение структуры
type Engine struct {
Power int
}
func (e Engine) Start() {
fmt.Println("Engine started with power:", e.Power)
}
// Определение другой структуры, которая включает первую
type Car struct {
Brand string
Engine
}
func main() {
myCar := Car{
Brand: "Toyota",
Engine: Engine{Power: 150},
}
fmt.Println("Car brand:", myCar.Brand)
myCar.Start() // Вызов метода встроенной структуры
}
Определяют набор методов, которые должны быть реализованы типом. Любой тип, реализующий все методы интерфейса, автоматически рассматривается как реализующий этот интерфейс. Это дает возможность полиморфизма.
package main
import "fmt"
// Определение интерфейса
type Drivable interface {
Drive()
}
// Определение структуры, реализующей интерфейс
type Car struct {
Brand string
}
func (c Car) Drive() {
fmt.Println(c.Brand, "is driving")
}
// Еще одна структура, реализующая интерфейс
type Bike struct {
Brand string
}
func (b Bike) Drive() {
fmt.Println(b.Brand, "is driving")
}
// Функция, принимающая интерфейс
func StartDriving(d Drivable) {
d.Drive()
}
func main() {
car := Car{Brand: "Toyota"}
bike := Bike{Brand: "Yamaha"}
StartDriving(car)
StartDriving(bike)
}
Интерфейсы также могут быть встроены друг в друга, что позволяет создавать сложные структуры интерфейсов.
package main
import "fmt"
// Определение базового интерфейса
type Printer interface {
Print()
}
// Определение другого интерфейса, включающего первый
type AdvancedPrinter interface {
Printer
Scan()
}
// Реализация структуры, реализующей расширенный интерфейс
type MultiFunctionPrinter struct{}
func (m MultiFunctionPrinter) Print() {
fmt.Println("Printing...")
}
func (m MultiFunctionPrinter) Scan() {
fmt.Println("Scanning...")
}
func main() {
mfp := MultiFunctionPrinter{}
mfp.Print()
mfp.Scan()
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
- Нет классов, используется композиция через структуры и методы.
- Полиморфизм достигается с помощью интерфейсов.
- Наследования нет, встраивание заменяет его.
2. C#:
- Полноценное ООП: классы, наследование, абстракция, интерфейсы.
- Поддержка модификаторов доступа (public, private, protected).
- Разработано для объектно-ориентированной модели с полной поддержкой инкапсуляции и полиморфизма.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊3👍1