Содержание
Разбираемся с пакетом Context в Golang / Хабр
Пакет context в Go полезен при взаимодействиях с API и медленными процессами, особенно в production-grade системах, которые занимаются веб-запросами. С его помощью можно уведомить горутины о необходимости завершить свою работу.
Ниже небольшое руководство, которое поможет использовать этот пакет в ваших проектах, а также расскажет о некоторых лучших практиках и подводных камнях.
(Прим. пер.: Контекст используется во многих пакетах, например, в работе с Docker).
Перед тем, как начать
Чтобы использовать контексты, вы должны понимать, что такое горутина и каналы. Я постараюсь кратко их рассмотреть. Если вы с ними уже знакомы, переходите непосредственно к разделу Контекст (Context).
Горутина
В официальной документации говорится, что «Горутина — это легковесный поток выполнения». Горутины легче, чем потоки, поэтому управление ими сравнительно менее ресурсозатратно.
→ Песочница
package main import "fmt" // Функция, которая выводит Hello func printHello() { fmt. Println("Hello from printHello") } func main() { // Встроенная горутина // Определяем функцию внутри и вызываем ее go func(){fmt.Println("Hello inline")}() // Вызываем функцию как горутину go printHello() fmt.Println("Hello from main") }
Если вы запустите эту программу, то увидите, что распечатывается только Hello from main
. На самом деле запускается обе горутины, но main
завершает работу раньше. Значит, горутинам нужен способ сообщать main
об окончании своего выполнения, и чтобы та ждала этого. Здесь нам на помощь приходят каналы (channels).
Каналы (channels)
Каналы — это способ коммуникации между горутинами. Они используются, когда вы хотите передать результаты, ошибки или другую информацию от одной горутины другой. Каналы бывают разных типов, например, канал типа int
получает целые числа, а канал типа error
— ошибки, и т.д.
Скажем, у нас есть канал ch
типа int
. Если вы хотите послать что-то в канал, синтаксис будет ch <- 1
. Что-то получить из канала можно так: var := <- ch
, т.е. забрать из канала значение и сохранить его в переменной var
.
Следующий код иллюстрирует, как, используя каналы, получить подтверждение, что горутины завершили свою работу и вернули свои значения в main
.
Прим.: Для синхронизации также могут использоваться группы ожидания, но в этой статье для примеров кода я выбрал каналы, поскольку дальше мы их используем в разделе о контекстах.
→ Песочница
package main import "fmt" // Печатает на стандартный вывод и отправляет int в канал func printHello(ch chan int) { fmt.Println("Hello from printHello") // Посылает значение в канал ch <- 2 } func main() { // Создаем канал. Для этого нам нужно использовать функцию make // Каналы могут быть буферизированными с заданным размером: // ch := make(chan int, 2), но это выходит за рамки данной статьи. ch := make(chan int) // Встроенная горутина. Определим функцию, а затем вызовем ее. // Запишем в канал по её завершению go func(){ fmt.Println("Hello inline") // Отправляем значение в канал ch <- 1 }() // Вызываем функцию как горутину go printHello(ch) fmt.Println("Hello from main") // Получаем первое значение из канала // и сохраним его в переменной, чтобы позже распечатать i := <- ch fmt.Println("Received ",i) // Получаем второе значение из канала // и не сохраняем его, потому что не будем использовать <- ch }
Контекст (Context)
Пакет context в go позволяет вам передавать данные в вашу программу в каком-то «контексте». Контекст так же, как и таймаут, дедлайн или канал, сигнализирует прекращение работы и вызывает return.
Для примера, если вы делаете веб-запрос или выполняете системную команду, будет хорошей идеей использовать таймаут для production-grade систем. Потому что, если API, к которому вы обращаетесь, работает медленно, вы вряд ли захотите накапливать запросы у себя в системе, поскольку это может привести к увеличению нагрузки и снижению производительности при обработке собственных запросов. В результате возникает каскадный эффект.
И здесь как раз может пригодиться контекст тайм-аута или дедлайна.
Создание контекста
Пакет context позволяет создавать и наследовать контекст следующими способами:
context.Background() ctx Context
Эта функция возвращает пустой контекст. Она должна использоваться только на высоком уровне (в main или обработчике запросов высшего уровня). Он может быть использован для получения других контекстов, которые мы обсудим позже.
ctx, cancel := context.Background()
Прим. пер.: В оригинале статьи имеется неточность, правильный пример использования context.Background
будет следующий:
ctx := context.Background()
context.TODO() ctx Context
Эта функция также создает пустой контекст. И она тоже должна использоваться только на высоком уровне или когда вы не уверены, какой контекст использовать, или если в функции еще нет получения нужного контекста. Это значит, что вы (или тот, кто поддерживает код) планируете позже добавить контекст в функцию.
ctx, cancel := context.TODO()
Прим. пер.: В оригинале статьи имеется неточность, правильный пример использования context.TODO
будет следующий:
ctx := context.TODO()
Что интересно, взгляните на код, это абсолютно то же самое, что и background. Разница лишь в том, что в данном случае можно пользоваться инструментами статического анализа для проверки валидности передачи контекста, что является важной деталью, поскольку эти инструменты помогают выявлять потенциальные ошибки на ранней стадии и могут быть включены в CI/CD пайплайн.
Отсюда:
var ( background = new(emptyCtx) todo = new(emptyCtx) )
context.WithValue(parent Context, key, val interface{}) (ctx Context, cancel CancelFunc)
Прим. пер.: В оригинале статьи имеется неточность, правильная сигнатура для context.WithValue
будет следующей:
context. WithValue(parent Context, key, val interface{}) Context
Эта функция принимает контекст и возвращает производный от него контекст, в котором значение val
связано с key
и проходит через всё контекстное дерево. То есть, как только вы создадите контекст WithValue
, любой производный контекст получит это значение.
Не рекомендуется передавать критические параметры, используя значения контекста, вместо этого функции должны принимать их в сигнатуре явным образом.
ctx := context.WithValue(context.Background(), key, "test")
context.WithCancel(parent Context) (ctx Context, cancel CancelFunc)
Здесь становится чуть интереснее. Эта функция создает новый контекст из переданного ей родительского. Родителем может быть контекст background или контекст, переданный в качестве аргумента функции.
Возвращается производный контекст и функция отмены. Вызывать функцию отмены контекста должна только та функция, которая его создает. Вы можете передавать функцию отмены другим функциям, если хотите, но это настоятельно не рекомендуется. Обычно это решение принимается от непонимания работы отмены контекста. Из-за этого порожденные от этого родителя контексты могут повлиять на программу, что приведет к неожиданному результату. Короче говоря, лучше НИКОГДА не передавайте функцию отмены.
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2 * time.Second))
Прим. пер.: В оригинале статьи автор, видимо, ошибочно для context.WithCancel
привёл пример с context.WithDeadline
. Правильный пример для context.WithCancel
будет следующим:
ctx, cancel := context.WithCancel(context.Background())
context.WithDeadline(parent Context, d time.Time) (ctx Context, cancel CancelFunc)
Эта функция возвращает производный контекст от своего родителя, который отменяется после дедлайна или вызова функции отмены. Например, вы можете создать контекст, который автоматически отменяется в определенное время и передает это дальше в дочерние функции. Когда этот контекст отменяется после дедлайна, все функции, у которых есть этот контекст, по уведомлению должны закончить работу.
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2 * time.Second))
context.WithTimeout(parent Context, timeout time.Duration) (ctx Context, cancel CancelFunc)
Эта функция похожа на context.WithDeadline. Разница в том, что в качестве входных данных используется длительность времени. Эта функция возвращает производный контекст, который отменяется при вызове функции отмены или по истечении времени.
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2 * time.Second))
Прим. пер.: В оригинале статьи автор, видимо, ошибочно для context.WithTimeout
привёл пример с context.WithDeadline
. Правильный пример для context.WithTimeout
будет следующим:
ctx, cancel := context.WithTimeout(context.Background(), 2 * time.Second)
Приём и использование контекстов в ваших функциях
Теперь, когда мы знаем, как создавать контексты (Background и TODO) и как порождать контексты (WithValue, WithCancel, Deadline и Timeout), давайте обсудим, как их использовать.
В следующем примере вы можете видеть, что функция, принимающая контекст, запускает горутину и ожидает ее возврата или отмены контекста. Оператор select помогает нам определить, что случится первым, и завершить работу функции.
После закрытия канала Done <-ctx.Done()
выбирается случай case <-ctx.Done():
. Как только это происходит, функция должна прервать работу и подготовиться к возврату. Это означает, что вы должны закрыть любые открытые соединения, освободить ресурсы и вернуться из функции. Бывают случаи, когда освобождение ресурсов может задержать возврат, например, зависает очистка. Вы должны иметь это в виду.
Пример, который следует за этим разделом, это полностью готовая программа на go, которая иллюстрирует timeout’ы и функции отмены.
// Функция, выполняющая какую-то медленную работу с использованием контекста // Заметьте, что контекст - это первый аргумент func sleepRandomContext(ctx context.Context, ch chan bool) { // Выполнение (прим. пер.: отложенное выполнение) действий по очистке // Созданных контекстов больше нет // Следовательно, отмена не требуется defer func() { fmt.Println("sleepRandomContext complete") ch <- true }() // Создаем канал sleeptimeChan := make(chan int) // Запускаем выполнение медленной задачи в горутине // Передаём канал для коммуникаций go sleepRandom("sleepRandomContext", sleeptimeChan) // Используем select для выхода по истечении времени жизни контекста select { case <-ctx.Done(): // Если контекст истекает, выбирается этот случай // Высвобождаем ресурсы, которые больше не нужны из-за прерывания работы // Посылаем сигнал всем горутинам, которые должны завершиться (используя каналы) // Обычно вы посылаете что-нибудь в канал, // ждете выхода из горутины, затем возвращаетесь // Или используете группы ожидания вместо каналов для синхронизации fmt. Println("Time to return") case sleeptime := <-sleeptimeChan: // Этот вариант выбирается, когда работа завершается до отмены контекста fmt.Println("Slept for ", sleeptime, "ms") } }
Пример
Как мы увидели, с помощью контекстов можно работать с дедлайнами, таймаутами, а также вызвать функцию отмены, тем самым дав понять всем функциям, использующим производный контекст, что надо завершить свою работу и выполнить return. Рассмотрим пример:
функция main
:
- Создает контекст с функцией отмены
- Вызывает функцию отмены по истечении произвольного таймаута
функция doWorkContext
:
- Создаёт производный контекст с тайм-аутом
- Этот контекст отменяется, когда функция main вызывает cancelFunction, истекает таймаут, либо doWorkContext вызывет свою cancelFunction.
- Запускает горутину для выполнения какой-нибудь медленной задачи, передавая полученный контекст
- Ждет завершения горутины или отмены контекста от main, в зависимости от того, что произойдет первым
функция sleepRandomContext
:
- Запускает горутину для выполнения какой-нибудь медленной задачи
- Ждет, пока завершится горутина, или
- Ждет отмены контекста функцией main, таймаута или вызова своей собственной cancelFunction
функция sleepRandom
:
- Засыпает на рандомное время
В этом примере используется спящий режим для имитации случайного времени обработки, в реальности же вы можете использовать каналы, чтобы сигнализировать этой функции о начале очистки и ждать из канала подтверждения, что очистка завершена.
Песочница (Выглядит так, будто рандомное время, которое я использую в песочнице, практически не меняется. Попробуйте выполнить это на вашем локальном компьютере, чтобы увидеть случайность)
→ Github
package main import ( "context" "fmt" "math/rand" "Time" ) // Медленная функция func sleepRandom(fromFunction string, ch chan int) { // Отложенная функция очистки defer func() { fmt.Println(fromFunction, "sleepRandom complete") }() // Выполним медленную задачу // В качестве примера, // «заснем» на рандомное время в мс seed := time.Now().UnixNano() r := rand.New(rand.NewSource(seed)) randomNumber := r.Intn(100) sleeptime := randomNumber + 100 fmt.Println(fromFunction, "Starting sleep for", sleeptime, "ms") time.Sleep(time.Duration(sleeptime) * time.Millisecond) fmt.Println(fromFunction, "Waking up, slept for ", sleeptime, "ms") // Напишем в канал, если он был передан if ch != nil { ch <- sleeptime } } // Функция, выполняющая медленную работу с использованием контекста // Заметьте, что контекст - это первый аргумент func sleepRandomContext(ctx context. Context, ch chan bool) { // Выполнение (прим. пер.: отложенное выполнение) действий по очистке // Созданных контекстов больше нет // Следовательно, отмена не требуется defer func() { fmt.Println("sleepRandomContext complete") ch <- true }() // Создаем канал sleeptimeChan := make(chan int) // Запускаем выполнение медленной задачи в горутине // Передаем канал для коммуникаций go sleepRandom("sleepRandomContext", sleeptimeChan) // Используем select для выхода по истечении времени жизни контекста select { case <-ctx.Done(): // Если контекст отменен, выбирается этот случай // Это случается, если заканчивается таймаут doWorkContext или // doWorkContext или main вызывает cancelFunction // Высвобождаем ресурсы, которые больше не нужны из-за прерывания работы // Посылаем сигнал всем горутинам, которые должны завершиться (используя каналы) // Обычно вы посылаете что-нибудь в канал, // ждете выхода из горутины, затем возвращаетесь // Или используете группы ожидания вместо каналов для синхронизации fmt. Println("sleepRandomContext: Time to return") case sleeptime := <-sleeptimeChan: // Этот вариант выбирается, когда работа завершается до отмены контекста fmt.Println("Slept for ", sleeptime, "ms") } } // Вспомогательная функция, которая в реальности может использоваться для разных целей // Здесь она просто вызывает одну функцию // В данном случае, она могла бы быть в main func doWorkContext(ctx context.Context) { // От контекста с функцией отмены создаём производный контекст с тайм-аутом // Таймаут 150 мс // Все контексты, производные от этого, завершатся через 150 мс ctxWithTimeout, cancelFunction := context.WithTimeout(ctx, time.Duration(150)*time.Millisecond) // Функция отмены для освобождения ресурсов после завершения функции defer func() { fmt.Println("doWorkContext complete") cancelFunction() }() // Создаем канал и вызываем функцию контекста // Можно также использовать группы ожидания для этого конкретного случая, // поскольку мы не используем возвращаемое значение, отправленное в канал ch := make(chan bool) go sleepRandomContext(ctxWithTimeout, ch) // Используем select для выхода при истечении контекста select { case <-ctx. Done(): // Этот случай выбирается, когда переданный в качестве аргумента контекст уведомляет о завершении работы // В данном примере это произойдёт, когда в main будет вызвана cancelFunction fmt.Println("doWorkContext: Time to return") case <-ch: // Этот вариант выбирается, когда работа завершается до отмены контекста fmt.Println("sleepRandomContext returned") } } func main() { // Создаем контекст background ctx := context.Background() // Производим контекст с отменой ctxWithCancel, cancelFunction := context.WithCancel(ctx) // Отложенная отмена высвобождает все ресурсы // для этого и производных от него контекстов defer func() { fmt.Println("Main Defer: canceling context") cancelFunction() }() // Отмена контекста после случайного тайм-аута // Если это происходит, все производные от него контексты должны завершиться go func() { sleepRandom("Main", nil) cancelFunction() fmt. Println("Main Sleep complete. canceling context") }() // Выполнение работы doWorkContext(ctxWithCancel) }
Подводные камни
Если функция использует контекст, убедитесь, что уведомления об отмене обрабатываются должным образом. Например, что exec.CommandContext
не закрывает канал чтения, пока команда не выполнит все форки, созданные процессом (Github), т.е., что отмена контекста не приведет к немедленному возврату из функции, если вы ждете с cmd.Wait(), пока все форки внешней команды не завершат обработку.
Если вы используете таймаут или дедлайн с максимальным временем выполнения, он может работать не так, как ожидается. В таких случаях, лучше реализовать таймауты с помощью time.After
.
Лучшие практики
- context.Background следует использовать только на самом высоком уровне, как корень всех производных контекстов.
- context.TODO должен использоваться, когда вы не уверены, что использовать, или если текущая функция будет использовать контекст в будущем.
- Отмены контекста рекомендуются, но эти функции могут занимать время, чтобы выполнить очистку и выход.
- context.Value следует использовать как можно реже, и его нельзя применять для передачи необязательных параметров. Это делает API непонятным и может привести к ошибкам. Такие значения должны передаваться как аргументы.
- Не храните контексты в структуре, передавайте их явно в функциях, предпочтительно в качестве первого аргумента.
- Никогда не передавайте nil-контекст в качестве аргумента. Если сомневаетесь, используйте TODO.
- Структура
Context
не имеет метода cancel, потому что только функция, которая порождает контекст, должна его отменять.
От переводчика
В нашей компании мы активно используем пакет Context при разработке серверных приложений для внутреннего использования. Но такие приложения для нормального функционирования, помимо Контекста, требуют дополнительных элементов, таких как:
- Логирование
- Обработка сигналов на завершение приложений, reload и logrotate
- Работа с pid-файлами
- Работа с конфигурационными файлами
- И другое
Поэтому в какой-то момент мы решили обобщить весь накопленный нами опыт и создали вспомогательные пакеты, значительно упрощающие написание приложений (особенно приложений, имеющих API). Свои разработки мы выложили в открытый доступ и любой желающий может ими воспользоваться. Ниже приводятся некоторые ссылки на пакеты, полезные для решения таких задач:
- nxs-go-appctx
- nxs-go-conf
Также читайте другие статьи в нашем блоге:
- Три простых приема для уменьшения Docker-образов
- Бэкапы Stateful в Kubernetes
- Резервное копирование большого количества разнородных web-проектов
- Telegram-бот для Redmine. Как упростить жизнь себе и людям
Личный контекст
Переход от массовых коммуникаций к персональным в самом разгаре. Закончится он смертью рекламы в ее нынешнем виде. Реклама будущего, по-видимому, полностью растворится в контенте.
Я часто пытаюсь представить себе, каким окажется будущее рекламы и маркетинга. Это здорово развивает воображение и помогает придумывать интересные идеи для клиентов уже сегодня.
Но будущее прорастает из настоящего. Сейчас, например, можно воочию наблюдать, как рекламщики, маркетологи, айтишники, психологи и представители множества других профессий с разных сторон пытаются решить одну и ту же задачу. Обозначим ее так: создание искусственного контекстного интеллекта.
Что такое идеальная маркетинговая коммуникация? Это когда человек получает сообщение, созданное с учетом его вкусов, интересов, местонахождения и настроения в конкретный момент. Вот это и призван обеспечивать в будущем контекстный интеллект. Для этого ему необходимо, во-первых, владеть большим массивом данных о человеке, включая его эстетические и вкусовые предпочтения, а во-вторых, уметь использовать эти сведения, предоставляя человеку максимально релевантную информацию. БОльшая часть этой фантазии уже реально осуществима. Социальные сети «знают» не только о поле, возрасте, образовании и месте работы своих пользователей, но и о любимых местах, актерах, музыке, ТВ-программах, ресторанах, даже о местоположении. А Google учитывает при новых запросах в поисковой системе все предыдущие запросы пользователя, дабы выдать ему наиболее подходящие результаты.
Рекламщики, маркетологи, айтишники, психологи и представители множества других профессий с разных сторон пытаются решить одну и ту же задачу. Обозначим ее так: создание искусственного контекстного интеллекта
Председатель совета директоров Google Эрик Шмидт как-то справедливо заметил, что пользователю скоро будет сложно получить информацию, которая не предназначена персонально для него. Эти слова обещают неминуемый закат эры массовых коммуникаций и начало эпохи, когда каждое сообщение будет формироваться для каждого потребителя индивидуально. Для этого и понадобится контекстный интеллект. Думаю, с его появлением все испытают чувство несказанного облегчения: слишком уж серьезную информационную перегрузку испытывает сейчас каждый человек.
Давайте включим воображение и постараемся представить, как станет работать в будущем контекстный интеллект на благо потребителя и производителя, решившего отрекламировать, к примеру, свой смартфон. Представим, что есть некая девушка по имени Евгения. Ее профиль и «активности» в социальной сети свидетельствуют о том, что она любит сериал «Доктор Хаус», по субботам ходит в кафе с подругами, больше всего общается с Аней, часто публикует фотографии, на которых запечатлена с неким Владимиром, и при этом является обладательницей смартфона HTC. Маркетинговая коммуникация будущего в этом случае могла бы выглядеть следующим образом. Во время просмотра очередной серии сериала сам доктор Хаус вдруг с экрана запросто обращается к ней: «Евгения, привет! Видел тебя в субботу в кафе «Прадо» с Аней. Кстати, я заметил, что ты намучилась с плохим Wi-Fi, маленьким дисплеем и устаревшей камерой твоего HTС! Если ты хочешь произвести впечатление на Владимира и делать более эффектные фотки, почитай мое письмо с рассказом о новом iPhone 77…» Как вы думаете, отреагирует Евгения на подобную рекламу? И понадобится ли рекламодателю для эффективного запоминания обращаться к ней с таким сообщением более одного раза?
Сочетание контента со знанием контекста покупателя позволяет не просто передавать маркетинговое сообщение, но и выстраивать доверительные отношения с ним. Сегодня уже понятно, что на протяжении всех предыдущих двухсот лет существования рекламы производителям было абсолютно наплевать, что на самом деле занимает их покупателя: они готовы были самовлюбленно говорить лишь о своих продуктах и брендах (и я тоже — чего уж греха таить! — был на той стороне баррикад). Однако сегодня покупатель становится центром всего маркетинга, и этот тренд, совершенно очевидно, будет развиваться. Завтра покупателям уже окажется недостаточно того, что продукты, которые они приобретают, — известные! Им еще будет важно, насколько эти продукты ценны в решении их собственных задач, а это потребует более глубокого взаимного исследования и общения. Можно сказать, что этап влюбленности между брендами и потребителями завершился — и начинаются серьезные «супружеские» отношения, когда важны не только красота, одежда и макияж, но и умение готовить, помогать по хозяйству и решать бытовые проблемы. Иначе брак по расчету не сложится.
Это значит, что почти все неконтекстные рекламные инструменты попросту отомрут: телевизионная реклама (будущее самого традиционного ТВ с сеткой вещания, впрочем, тоже весьма печально), баннеры, раздача листовок и проч. На их могильной плите будет написано: «Нерелевантные коммуникации. R.I.P.». Не исключаю даже появления закона, предписывающего рекламодателю получать согласие потребителей на передачу рекламных сообщений.
Наружной рекламе, пожалуй, удастся выжить — при условии что она станет более интерактивной. Реклама в глянцевых печатных изданиях тоже вряд ли исчезнет полностью, как и сами глянцевые издания: красивые фотографии красивых людей и вещей имеют художественную ценность — а значит, привлекают внимание.
Уже сегодня важной задачей маркетинга является создание собственного контента, основанного на инсайтах потребителей, а также интеграция маркетингового сообщения в готовый контент и его использование в реальном времени. Маркетинг в реальном времени подразумевает поиск подходящего для вашего продукта контекста и немедленное внедрение в него своего маркетингового сообщения.
Если контекстная реклама сегодня существует только в поисковиках, то в будущем подобное станет возможным и на форумах, и в социальных сетях, и в обсуждениях в блогах и на сайтах. Работать система будет примерно так. При появлении в сети контекста, уместного для размещения маркетингового контента, роботы по алгоритму подбирают из вашей библиотеки нужное наполнение, адаптируют к общей тональности информационного ресурса, времени суток, дня недели, географии участников — и размещают сообщение. Например, описанная выше девушка Евгения начинает интересоваться новым смартфоном: просит совета у друзей в соцсетях, задает вопрос в Twitter. Такая активность должна немедленно послужить сигналом контекстному интеллекту: возникла благоприятная ситуация для маркетинга мобильных телефонов, пора показывать пользователю отзывы других людей, особенно если среди них есть друзья Евгении.
В будущем работа профессионалов в сфере маркетинга сосредоточится на создании и развитии алгоритмов по персонализации маркетинговых сообщений о продукте и их передаче в возникающих ежедневно контекстах. Работу грядущих профессионалов маркетинга я бы назвал информационным строительством. Их задачей станет формировать информационное поле вокруг продукта, услуги, бренда или даже человека, призванное передавать их основную ценность и привлекать к нему людей, которым эта ценность поможет в достижении их целей. Ведь каждый продукт, бренд или человек появились на свет с какой-то целью. Благодатное информационное поле для многих продуктов можно обнаружить и сейчас. Хороший пример — сериал «Секс в большом городе», представляющий собой прекрасный контекст для передачи маркетинговых сообщений. Больше того, в этом контексте выстроена прямая ассоциативная связь между словами «секс» и «шопинг», потому что, несмотря на название, б’ольшую часть времени (и денег) главные герои все-таки тратят на покупки. В будущем производители контента займутся созданием контекстов для определенных маркетинговых сообщений, а интеграция будет происходить не на этапе производства, а в процессе потребления.
С появлением социальных сетей каждый человек получил возможность заявлять о себе всему миру и рассказывать о своих способностях и ценности для других людей. Чем выше эти возможности, тем шире информационное поле вокруг человека. Подозреваю, что в будущем для победы в войне не понадобится физически никого уничтожать: достаточно будет лишь уничтожить информационное поле вокруг противника, «выключить» его из контекстов. Так что контекст — не такая уж безобидная штука, как может показаться.
Смотрите не просмотрите. Каждый день!
Что такое сокращение для контекста?
Аббревиатура » Термин
Термин » Аббревиатура
Слово в термине
#ABCDEFGHIJKLMNOPQRSTUVWXYZ НОВЫЙ
Сокр. » Срок
Срок » Сокр.
Слово в термине
Фильтровать по: Выбрать категорию из списка…──────────ВсеНовости и СМИ (1)ИТ (2)Энергетика (1)
Срок
Определение
Опции
Рейтинг
C | Context Community » News & Media | Rate it: | |||
CTX | Context Computing » IT | Rate it: | |||
CXT | Context Computing » IT | Оценить: | |||
C | Контекст Правительственный » Энергетика | 90 Оценить0083 |
Что означает
в контексте ?
- контекст, лингвистический контекст, контекст употребления (существительное)
- дискурс, который окружает языковую единицу и помогает определить ее интерпретацию
подробнее »
Знаете, что такое
контекст ? Есть еще одно хорошее объяснение контекста ? Не держите это в себе!
Все еще не можете найти искомое определение аббревиатуры? Используйте нашу технологию Power Search , чтобы искать более уникальные определения в Интернете!
Цитата
Используйте приведенные ниже параметры цитирования, чтобы добавить эти сокращения в свою библиографию.
Самый большой ресурс в Интернете для
Акронимы и сокращения
Член сети STANDS4
Просмотреть Abbreviations.com
#ABCDEFGHIJKLMNOPQRSTUVWXYZ
Бесплатно, регистрация не требуется:
Добавить в Chrome
Получите мгновенное объяснение любой аббревиатуры или аббревиатуры, которая попадется вам в любом месте в Интернете!
Бесплатно, регистрация не требуется:
Добавить в Firefox
Получите мгновенное объяснение любой аббревиатуры или аббревиатуры, которая попадется вам в любом месте в Интернете!
Викторина
Окончательный тест аббревиатуры
»
Полный привод
А. 4 недели в пути
B. Полный привод
C. 4 рабочих дня
D. 4 дня волны
Вставить
Поделиться изображением контекста
»
Нажмите, чтобы просмотреть:
Что такое контекст — определение и примеры для писателей
Определение содержания и контекста
Что означает контекст?
Осознаем мы это или нет, контекст окружает нас повсюду. Это фундаментальный способ, которым мы приходим к пониманию людей, ситуаций и идей. Все, что мы думаем, говорим, видим, слышим и делаем, является реакцией на внешние раздражители мира.
И то, как мы относимся к этим стимулам, во многом зависит от контекста, в котором они нам представлены. Чтобы узнать больше об этой идее, посмотрите видео из Оклендского университета ниже.
Что такое контекст? От University of Auckland
Итак, вы, вероятно, думаете: «Хорошо, это хорошо, и все такое, но что такое контекст? Конечно, смысл не может быть таким расплывчатым. Ну, это и не так.
Но, поняв основные аспекты этого термина, мы лучше подготовимся к его осмысленному применению. Итак, без лишних слов, давайте углубимся в формальное определение контекста.
ОПРЕДЕЛЕНИЕ КОНТЕКСТА
Что такое контекст?
Контекст — это грани ситуации, вымышленной или не вымышленной, которые вдохновляют чувства, мысли и убеждения групп и отдельных лиц. Это исходная информация, которая позволяет людям принимать обоснованные решения. Большую часть времени взгляд человека на предмет будет сделан в ответ на представленный контекст. В сторителлинге это все, что окружает персонажей и сюжет, чтобы дать им определенную перспективу. Ни одна история не происходит без контекстуальной информации и элементов.
Характеристики контекста:
- Информация, которая нам представлена
- Используется в аргументативном смысле
- Предвзятая/субъективная форма обучения
Контекстная информация
, есть только два вида контекста: нарратив и ненарратив.
Первый дает нам информацию об истории, а второй дает нам информацию обо всем, что находится за пределами истории.
Типы контекста повествования включают:
- Персонаж
- Сюжет
- Сеттинг
Контекст повествования — это все, что объясняет, «что происходит» в истории. Возьмем, к примеру, комедийный сериал, такой как «Офис »: в сериале есть много моментов, которые не имели бы смысла без контекстной информации — и так уж случилось, что есть видео, в котором «Офис » исследуется «вне контекста». ».
Что означает контекст в офисе?
Даже самые ярые поклонники Office могут задаться вопросом: «Что, черт возьми, происходит?» когда представлены эти клипы вне контекста. В соцсетях кадры из фильмов и телепередач часто представлены вот так — как этот скриншот из The Good Place .
Определение контекста и примеры
В некотором смысле вырванные из контекста моменты сами по себе стали разновидностью юмора. Но важно, чтобы мы также учитывали, как информация за пределами повествования может повлиять на наши чувства по поводу истории.
К неповествовательным типам контекста относятся:
- Исторический
- Авторский
- Критический
Неповествовательный контекст — это все, что находится за пределами истории и влияет на наши мысли и мнения по предмету. Возьмем, к примеру, «В Хладнокровие » Трумэна Капоте: когда мы узнаем об обстоятельствах, выходящих за рамки предмета, мы не можем относиться к этой истории так же.
В Хладнокровие — роман-расследование об убийстве семьи из четырех человек в Холкомбе, штат Канзас. Капоте всерьез начал писать об убийствах, а затем расширил свое исследование до полноценного романа — конечный результат говорит сам за себя — мало того, что проза Капоте считается одной из величайших за всю историю, она также стала пионером в написании реальных преступлений.
Но когда In Cold Blood рассматривается в контексте человека, написавшего его, обстановки, в которой оно происходило, и старшинства его написания, смысл может измениться. Два осужденных убийцы в романе, Перри Смит и Дик Хикок, брали интервью у Капоте в процессе написания.
Их показания включены в роман, но отфильтрованы Капоте. Таким образом, для нас было бы безответственно говорить, что их показания правдивы, учитывая контекст, в котором они были написаны.
В другом месте критики утверждают, что мы можем судить о произведении искусства только на основе достоинств самого искусства, а не контекста, в котором оно было создано. Французский теоретик литературы Ролан Барт сказал, что «текст» может говорить только сам за себя и что мысли и чувства автора не должны влиять на его достоинства. Чтобы узнать больше об этой теории «Смерти автора», посмотрите видео ниже.
Изучение контекстных подсказок • Линдси Эллис о «Смерти автора»
В последние годы многие фанаты критиковали Дж. К. Роулинг книги о Гарри Поттере в свете ее политических взглядов. Некоторые критики утверждают, что ее взгляды меняют смысл романов. Другие утверждают, что ее взгляды не должны иметь никакого влияния. Увы, «правильного» ответа не существует, но важно учитывать, как контекст, как внутри, так и вне истории, может влиять на читателей.
Контекстные подсказки задают тон
Как использовать контекст в качестве изложения
В сценарном искусстве есть слово, которое большинство сценаристов боится услышать… и это слово — изложение. Ах да, ужасная экспозиция — или пояснительное описание — известна тем, что убивает больше, чем несколько хороших сценариев. Итак, как сценаристы эффективно используют экспозицию? Ну, это начинается с потребности в контексте. Когда я говорю о необходимости, я имею в виду, что без нее история не имела бы никакого значения.
Мы импортировали сценарий On the Waterfront в программное обеспечение для написания сценариев StudioBinder, чтобы посмотреть на культовую сцену, где контекст является основной силой экспозиции.
В этой сцене Терри подробно описывает, как Чарли и Джонни бросили его. Эта предыстория или экспозиция добавляет необходимый контекст, необходимый для восклицания Терри: «Я мог бы быть соперником!» эффектный.
Нажмите на ссылку ниже, чтобы прочитать сцену.
Что такое контекст? • Прочитайте сценарий «На набережной» 9.0151
Это пояснительное описание устанавливает контекст, в котором мы можем увидеть, что Терри пережил «годы жестокого обращения». Контекст далее воспроизводится, поскольку Терри сетует на действия своих лучших друзей. Подумайте об этом так: правильная экспозиция должна действовать как чайник; каждая важная деталь делает чайник все горячее и горячее — или более контекстуальным и более контекстуальным — до тех пор, пока — напряжение не будет снято… и ура, конфликт разрешен.
Как добавить контекстные подсказки
Советы по включению контекста
Контекст играет огромную роль в управлении вниманием и эмоциональной привязанностью аудитории. Скажем, персонаж делает что-то очень плохое, например, убивает другого персонажа. Наша естественная склонность — очернять их, но если их действиям дать контекст, мы можем рассматривать их действия как героические.
Возьмите Ридли Скотта
Гладиатор например: когда Максимус убивает Коммода, мы рассматриваем его как героя. Давайте посмотрим, как разыгрывается эта сцена:
Примеры контекста в Gladiator
В контексте действия Максимуса оправданы. Коммод убил семью Максимуса и сфальсифицировал борьбу против него. Таким образом, имеет смысл, что мы болеем за его смерть. Вот несколько советов о том, как использовать контекст в своих работах:
- Проявите сочувствие к своему главному герою
- Очерните своего антагониста
- Максимизируйте конфликт
- Развивайте темы
- Отзовитесь к предыдущим событиям
Используя эти стратегии, вы создадите непрерывность повествования.