Backend
3.95K subscribers
35 photos
706 links
Комьюнити Backend программистов.
Python, Java, Golang, PHP, C#, C/C++, DevOps

Сайт easyoffer.ru
Реклама @easyoffer_adv
ВП @easyoffer_vp
Download Telegram
Напишите фрагмент кода, нарушающий принцип Don't Repeat Yourself (DRY). Объясните, почему у него плохая организация, и исправьте

Фрагмент кода, нарушающий принцип DRY (Don't Repeat Yourself), может выглядеть следующим образом:
def calculate_rectangle_area(width, height):
area = width * height
print(f"Площадь прямоугольника: {area}")

def calculate_square_area(side_length):
area = side_length * side_length
print(f"Площадь квадрата: {area}")

# Вычисление площади прямоугольника
calculate_rectangle_area(5, 10)

# Вычисление площади квадрата
calculate_square_area(5)


В этом примере кода нарушение принципа DRY происходит из-за дублирования логики вычисления площади. Обратите внимание, что у нас есть две похожие функции calculate_rectangle_area и calculate_square_area, каждая из которых выполняет похожую операцию вычисления площади, но для разных фигур.

Почему это плохо организовано и нарушает принцип DRY?


Дублирование кода: Обе функции содержат одинаковую логику вычисления площади (умножение двух чисел). Это приводит к дублированию кода, что делает его сложнее поддерживать и изменять в случае необходимости.

Нарушение модульности и повторное использование: При изменении логики вычисления площади (например, если мы хотим добавить поддержку других фигур), нам придется вносить изменения в несколько мест кода, что увеличивает риск ошибок и затрудняет его поддержку.

Как можно исправить это, соблюдая принцип DRY?


Cоздать одну универсальную функцию для вычисления площади, которая принимает тип фигуры в качестве параметра:
def calculate_area(shape, *args):
if shape == "rectangle":
width, height = args
area = width * height
print(f"Площадь прямоугольника: {area}")
elif shape == "square":
side_length = args[0]
area = side_length * side_length
print(f"Площадь квадрата: {area}")
else:
print("Неизвестная фигура")

# Вычисление площади прямоугольника
calculate_area("rectangle", 5, 10)

# Вычисление площади квадрата
calculate_area("square", 5)


В этом исправленном примере мы создали одну универсальную функцию calculate_area, которая принимает параметр shape для определения типа фигуры и переменное число аргументов args, которые передаются в зависимости от типа фигуры. Это позволяет нам избежать дублирования логики и сделать код более модульным и гибким для дальнейших изменений или расширений.
🤯9😁61
PHP

Реализуйте функцию findLargest(array $numbers) таким образом, чтобы она возвращала наибольшее число из целочисленного массива $numbers.

Note: массив всегда содержит по крайней мере одно число.


<?php /Starter code/?>
<?php
function findLargest(array $numbers) {
//Ваш код тут
}
?>


Жду ваши решения в комменты 👇
👍1
Active-Record

Active-Record
— шаблон проектирования, который поощряет внедрение в сам объект функций, таких как Insert, Update и Delete, и свойств, которые соответствуют столбцам некой базовой таблицы в базе данных.

Основная идея шаблона Active Record заключается в том, чтобы позволить объекту инкапсулировать данные и операции с базой данных, которые вы можете выполнять с ним. То есть, мы передаем классу некоторый набор значений, который затем внутри этого класса будет преобразован в запрос SQL и выполнен.

Такой подход позволяет нам не использовать запросы SQL напрямую. И кроме того, позволяет сделать код более безопасным, так как если нельзя выполнить любой запрос напрямую, то и выполнение SQL инъекций становится более затруднительным или даже невозможным.

Посмотрим простой пример:

@Entity

public class ChessPlayer extends PanacheEntity {

public String firstName;

public String lastName;

public LocalDate birthDate;

@Version

public int version;

public void setLastName(String lastName) {

this.lastName = lastName.toUpperCase();

}

}


В результате будет сформирован SQL запрос следующего вида:

  insert 

into

ChessPlayer

(birthDate, firstName, lastName, version, id)

values

(?, ?, ?, ?, ?)


Останется только добавить значения для соответствующих переменных при обращении к данному классу.
2👀2👍1
​​Что такое Кеширование?

Кеширование (Caching) - это техника оптимизации производительности, которая заключается в временном сохранении результатов вычислений, запросов или доступа к данным, чтобы обеспечить быстрый доступ к этим результатам при последующих запросах. Цель кеширования - уменьшить нагрузку на ресурсы системы и повысить отзывчивость приложения.

Основные принципы кеширования:


Уменьшение времени доступа: Запросы к данным из кэша обычно выполняются быстрее, чем запросы к источнику данных (например, базе данных или удаленному сервису), что сокращает время ожидания.

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

Улучшение масштабируемости: Кеширование способствует повышению производительности системы и обеспечивает более легкую масштабируемость при увеличении нагрузки.

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

Примеры кеширования:


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

• Кеширование на уровне сети:
Прокси-серверы или CDN (Content Delivery Network) могут кэшировать статические ресурсы (например, изображения, CSS, JavaScript), чтобы ускорить их доставку до конечных пользователей и снизить нагрузку на серверы.

• Кеширование на клиентской стороне:
Браузеры могут кэшировать загруженные ресурсы, такие как HTML, CSS, JavaScript и изображения, чтобы повторные запросы к веб-сайту были быстрее и более эффективными.
🔥51👍1
​​Какая разница между организацией кода и архитектурой?

Разница между организацией кода (code organization) и архитектурой (architecture) в разработке программного обеспечения заключается в том, что организация кода фокусируется на структуре, распределении и управлении самим кодом внутри проекта, в то время как архитектура определяет более высокоуровневую структуру системы, её компоненты, взаимодействия и принципы организации.

Организация кода (Code Organization):


• Организация кода касается того, как мы структурируем и управляем кодом внутри проекта.
• Это включает в себя правила и соглашения по именованию переменных, функций, классов, модулей и т.д., а также способы организации кода в файлы и директории.
• Цель организации кода - упростить поддержку, расширение и повторное использование кода.

# Пример структуры проекта Python
my_project/
├── main.py
├── utils/
│ ├── helper_functions.py
│ └── constants.py
├── models/
│ ├── user.py
│ └── post.py
└── tests/
├── test_utils.py
├── test_models.py
└── test_main.py


Архитектура (Architecture):


• Архитектура определяет структуру и организацию системы в целом, включая её компоненты, взаимодействия между компонентами, основные принципы проектирования и решения архитектурных проблем.
• Это высокоуровневое понятие, описывающее общую архитектурную концепцию системы, например, клиент-серверное взаимодействие, микросервисная архитектура, MVC (Model-View-Controller) и т.д.
• Цель архитектуры - обеспечить масштабируемость, надежность, безопасность и удобство сопровождения системы.

Пример архитектурных концепций:

MVC (Model-View-Controller): Разделение приложения на три основных компонента - модель (бизнес-логика и данные), представление (отображение данных на пользовательский интерфейс) и контроллер (управление взаимодействием между моделью и представлением).

Микросервисная архитектура: Разделение системы на небольшие автономные сервисы, каждый из которых выполняет определенную функцию и взаимодействует с другими сервисами посредством API.

Клиент-серверная архитектура: Разделение системы на клиентские приложения (которые отправляют запросы) и серверные приложения (которые обрабатывают запросы и предоставляют данные).

Таким образом, организация кода - это часть более широкого понятия архитектуры, которая фокусируется на том, как мы структурируем и управляем кодом внутри проекта, в то время как архитектура определяет общую структуру и организацию системы, включая её компоненты и взаимодействия.
🔥5👍4
Почему функциональное программирование это мейнстрим?

Интерес к функциональному программированию растет по нескольким причинам, связанным с эффективностью разработки, управлением состоянием, параллелизмом выполнения и другими факторами. Давайте рассмотрим подробнее, почему функциональное программирование становится все более популярным.

Иммутабельность данных (Immutable Data): Функциональное программирование поддерживает концепцию иммутабельности данных, где данные неизменяемы и не могут быть модифицированы после создания. Это упрощает понимание и предсказуемость поведения программы, поскольку отсутствует состояние, которое может меняться. Иммутабельность также способствует безопасности, особенно при параллельном выполнении кода.

// Пример на Scala с использованием неизменяемой коллекции
val numbers = List(1, 2, 3, 4, 5)
val doubledNumbers = numbers.map(_ * 2)


Функции высшего порядка (Higher-Order Functions): Функциональное программирование активно использует функции высшего порядка, которые могут принимать другие функции в качестве аргументов или возвращать их как результат. Это позволяет писать компактный и выразительный код, делая его более модульным и гибким.

// Пример на JavaScript с использованием функции высшего порядка
const applyOperation = (operation, x, y) => operation(x, y);
const add = (a, b) => a + b;
const result = applyOperation(add, 5, 3); // Результат: 8


Параллелизм и асинхронное программирование: Функциональное программирование способствует разработке параллельных и асинхронных приложений. Благодаря иммутабельности данных и отсутствию побочных эффектов, функциональные программы легче масштабируются и управляются в многопоточной среде.

# Пример на Elixir с использованием параллелизма
Enum.map([1, 2, 3, 4], fn x -> x * x end) # Результат: [1, 4, 9, 16]


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

-- Пример на Haskell с декларативным описанием задачи
sumOfSquares :: [Int] -> Int
sumOfSquares xs = sum (map (^2) xs)


Работа с состоянием без побочных эффектов: Функциональное программирование поощряет работу с данными и состоянием без использования изменяемых переменных и побочных эффектов. Это делает код более предсказуемым и облегчает отладку.

; Пример на Clojure с работой без побочных эффектов
(defn sum-of-squares [xs]
(reduce + (map #(* % %) xs)))


Интерес к функциональному программированию продолжает расти из-за его способности улучшать модульность, управление состоянием, распределение и параллелизм в разработке программного обеспечения.
👍4
👍2
🗓 Будьте осторожны с датами

with new_table as (
select
patient_id
, first_name
, last_name
, time(birth_date, '+1 second') as birth_date

from patients
where TRUE
and patient_id = 1

UNION

select
patient_id
, first_name
, last_name
, birth_date

from patients
WHERE TRUE
and patient_id != 1
)

select
birth_date

from new_table
where TRUE
and birth_date between '1953-12-05' and '1953-12-06'


В этой базе данных все даты сокращены до дня. Это означает, что все значения времени столбца Birthday_date в этом примере равны 00:00:00. Однако в реальных наборах данных это обычно не так.

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

В приведенном выше примере я искусственно добавил секунду к пациенту №1. Как видите, этой 1-й секунды было достаточно, чтобы исключить пациента из результатов при использовании ключевого слова BETWEEN.

Еще один распространенный пример, который чаще всего упускают из вида специалисты по работе с данными, — это присоединение к датам, в которых все еще есть временной компонент. В большинстве случаев они действительно пытаются присоединиться к столбцам с сокращенной датой и, в конечном итоге, не получают желаемого результата или, что еще хуже, они не осознают, что получили неправильный результат.
👍5
​​Задача: Генератор коротких ссылок

Ваша компания отправляет СМС с трекинговой ссылкой, но ссылка достаточно длинная и из-за этого СМС выходит за 70 символов (длина 1 СМС). Необходимо спроектировать сервис-«укорачиватель ссылок», чтобы сэкономить деньги компании. Интервьюер при этом выступает заказчиком со стороны бизнеса и ему можно задавать вопросы по сути задачи.

Задача хороша тем, что в нее можно углубляться по нескольким направлениям и оценить сразу несколько скиллов кандидата, а также глубину проработки (по сути его опыт), причём даже если он её уже решал (а многие действительно это делали).

Основные направления обсуждения:

как будем делать с точки зрения структуры приложения (в самом проекте/микросервисе и критерии, по которым мы делаем этот выбор). И тот, и другой варианты допустимы — все дело в аргументации. Если кандидат вообще не говорит про задачу с этой стороны, а, например, сразу переходит к структуре таблицы, то, скорее всего, кандидат никогда не задумывается над такими вопросами и/или не работал в более-менее крупных проектах;

структура данных и выбор хранилища (СУБД, key-value типа Redis, еще какие-то варианты, плюсы и минусы тех или иных вариантов). Опять же, в зависимости от вопросов кандидата и желания интервьюера можно подвести к выбору какого-то варианта, но в целом есть множество вариантов реализации, которые будут оправданы — опять же, вопрос в аргументации выбора;

хеши/коллизии, устойчивость к перебору ссылок (расчет количества необходимых вариантов). Важно, чтобы собеседуемый разработчик узнал про количество ссылок, оценил максимально возможную длину ссылки (и срок действия) и принял решение о том, какое количество символов стоит заложить в короткий URL. Плохо, если кандидат сильно перезакладывается или берет слишком маленькое количество символов, что может привести к тому, что допустимые комбинации в обозримом будущем закончатся;

дополнительно можно углубиться в смежные темы: деплой/мониторинг сервиса в том или ином виде в зависимости от выбора в предыдущих вопросах, приблизительная оценка ресурсов, минимально необходимых для эксплуатации, отказоустойчивость.
👍8
На вход подаются два неупорядоченных слайса любой длины. Надо написать функцию, которая возвращает их пересечение

Стандартная задача с leetcode и ее довольно часто спрашивают на собеседованиях в качестве простой задачи для разогрева.

Можно решить сортировкой, за более долгое время, но без выделения дополнительной памяти. А можно выделить дополнительную память и решить за линейное время.

Надо посчитать количество появлений элементов первого массива (лучше брать тот, что покороче) — используем для этого словарь. Потом пройтись по второму массиву и вычитать из словаря те элементы, которые есть в нем. По ходу добавляем в результат те элементы, у которых частота появлений больше нуля.

Решение (осторожно, много кода):


package main

import (
"fmt"
)

// На вход подаются два неупорядоченных массива любой длины.
// Необходимо написать функцию, которая возвращает пересечение массивов
func intersection(a, b []int) []int {
counter := make(map[int]int)
var result []int

for _, elem := range a {
if _, ok := counter[elem]; !ok {
counter[elem] = 1
} else {
counter[elem] += 1
}
}
for _, elem := range b {
if count, ok := counter[elem]; ok && count > 0 {
counter[elem] -= 1
result = append(result, elem)
}
}
return result
}

func main() {

a := []int{23, 3, 1, 2}
b := []int{6, 2, 4, 23}
// [2, 23]
fmt.Printf("%v\n", intersection(a, b))
a = []int{1, 1, 1}
b = []int{1, 1, 1, 1}
// [1, 1, 1]
fmt.Printf("%v\n", intersection(a, b))
}
👍8
​​Задачка на скорость

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

Решение:


def calc_angel(t: datetime.time) -> float:
h = t.hour
if h > 12:
h -= 12
hour_angle = 0.5 * (h * 60 + t.minute)
minute_angle = 6 * t.minute
angle = abs(hour_angle - minute_angle)
return min(angle, 360 - angle)


Пишите в комменты свои варианты решения задачи 👇
👍5🤯1
​​🔎 Поиск повторяющихся записей

SELECT 
first_name
, count() as ct

FROM patients
GROUP BY
first_name
HAVING
count() > 1
ORDER BY
COUNT(*) DESC
;


Таблица из примера — это упрощенная версия баз данных, которые вы будете использовать в своей работе. В большинстве случаев вы захотите выяснить причины дублирования значений в базе данных. Для этого вам пригодится данный запрос.

Вы можете использовать ключевое слово HAVING для сортировки повторяющихся значений. В таком случае вы заметите, что чаще всего дублируется имя Джон. Затем вы запустите еще один запрос, чтобы увидеть причину повторяющихся значений, и увидите, что все пациенты имеют разные фамилии и ID.
1👍1
​​Что такое Параллелизм?

Как можно одновременно выполнить две задачи? Очень просто — поручить их выполнение двум работникам (потокам). В этом суть параллелизма. Термин говорит сам за себя.

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

Возьмем простой пример. Вы поручили приготовить блюдо 3 поварам, каждый из которых должен работать отдельно с овощами, пастой и соусом. В итоге они потратили разное время: 2 минуты (на овощи), 1 минуту (на пасту), 3 минуты (на соус).

Как вы думаете, сколько времени ушло на приготовление блюда? 3 минуты!

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

Помимо этого, есть и другие проблемы, которые приходится решать при параллелизме (в отличие от многозадачности).

• Состояние гонки (race condition).
Гонка возникает, когда два процесса пытаются получить доступ к общей памяти. Это может создать проблемы. Представьте, что ваш банковский баланс равен $100, и вы одновременно проводите две транзакции, которые списывают $100. Что произойдет с банковским балансом — он станет 0 или -100? Эта ситуация должна быть правильно обработана в параллельных системах.

Передача сообщений (message passing).

Этот механизм задействуется, когда два потока изолированы друг от друга. Допустим, у вас есть две задачи, A и B, выполняемые параллельно. Как вы передадите результат задачи A задаче B, ведь они изолированы друг от друга? Здесь как раз и необходим механизм передачи сообщений.
👍1
Задача: Слить N каналов в один

Даны n каналов типа chan int. Надо написать функцию, которая смерджит все данные из этих каналов в один и вернет его.

Мы хотим, чтобы результат работы функции выглядел примерно так:

for num := range joinChannels(a, b, c) {

fmt.Println(num)

}


Для этого напишем функцию, которая будет асинхронно читать из исходных каналов, которые ей передадут в качестве аргументов, и писать в результирующий канал, который вернется из функции.

Создаем канал, куда будем сливать все данные. Он будет небуферезированный, потому что мы не знаем, сколько данных придет из каналов.

Дальше асинхронно прочитаем из исходных каналов и закроем результирующий канал для мерджа, когда все чтение закончится. Чтобы дождаться конца чтения, просто обернем этот цикл по каналам в wait group.

Решение с кодом закину следующим постом, так как кода будет много
Решение задачи «Слить N каналов в один»

package main

import (
"fmt"
"sync"
)

func joinChannels(chs ...<-chan int) <-chan int {
mergedCh := make(chan int)

go func() {
wg := &sync.WaitGroup{}

wg.Add(len(chs))

for _, ch := range chs {
go func(ch <-chan int, wg *sync.WaitGroup) {
defer wg.Done()
for id := range ch {
mergedCh <- id
}
}(ch, wg)
}

wg.Wait()
close(mergedCh)
}()

return mergedCh
}

func main() {

a := make(chan int)
b := make(chan int)
c := make(chan int)

go func() {
for _, num := range []int{1, 2, 3} {
a <- num
}
close(a)
}()

go func() {
for _, num := range []int{20, 10, 30} {
b <- num
}
close(b)
}()

go func() {
for _, num := range []int{300, 200, 100} {
c <- num
}
close(c)
}()

for num := range joinChannels(a, b, c) {
fmt.Println(num)
}

}
👍7
Что такое SOAP?

SOAP (Simple Object Access Protocol) - это протокол обмена сообщениями, который используется для передачи структурированных и формализованных данных между компьютерными системами через сеть. SOAP базируется на XML и используется для обмена данными между приложениями, работающими на различных платформах и написанными на разных языках программирования.

Основные характеристики SOAP:


Простота (Simple): SOAP предоставляет простой и легко понятный способ обмена структурированными данными между клиентом и сервером. Он определяет набор стандартных правил для форматирования и передачи сообщений.

Объектный доступ (Object Access): SOAP позволяет вызывать удаленные процедуры (RPC - Remote Procedure Calls) на удаленном сервере, позволяя клиенту вызывать методы и функции на сервере, как если бы они были локальными.

Протокол (Protocol): SOAP определяет стандартные правила для описания структуры сообщений, методов и параметров вызова. Он обеспечивает возможность сериализации и десериализации данных между различными платформами и языками.

Основные компоненты SOAP:


• SOAP Envelope: Определяет структуру SOAP-сообщения, включая обязательные элементы, такие как заголовок (Header) и тело (Body).
• SOAP Header: Может содержать дополнительные метаданные, такие как информация об аутентификации, авторизации, безопасности и т.д.
• SOAP Body: Содержит основные данные запроса или ответа. Фактическое содержимое сообщения передается внутри SOAP Body.

Пример SOAP-сообщения:

<soap:Envelope xmlns:soap="https://www.w3.org/2003/05/soap-envelope" xmlns:ns="https://example.com/">
<soap:Header/>
<soap:Body>
<ns:GetUserInfo>
<ns:UserID>123</ns:UserID>
</ns:GetUserInfo>
</soap:Body>
</soap:Envelope>


Пример SOAP-ответа:

<soap:Envelope xmlns:soap="https://www.w3.org/2003/05/soap-envelope" xmlns:ns="https://example.com/">
<soap:Header/>
<soap:Body>
<ns:GetUserInfoResponse>
<ns:UserName>John Doe</ns:UserName>
<ns:Email>[email protected]</ns:Email>
</ns:GetUserInfoResponse>
</soap:Body>
</soap:Envelope>
👍10
​​Чем REST лучше SOAP максимально содержательно и с примерами

REST (Representational State Transfer) и SOAP (Simple Object Access Protocol) - это два основных подхода к созданию веб-сервисов для обмена данными между клиентами и серверами. Вот несколько причин, по которым REST часто считается более привлекательным выбором по сравнению с SOAP:

Простота и легковесность:

REST основан на простом и легковесном архитектурном стиле, который использует стандартные протоколы HTTP (GET, POST, PUT, DELETE) для обмена данными. Это делает REST более простым в использовании и понимании по сравнению с SOAP, который требует более сложных протоколов, таких как HTTP+XML.

Использование стандартных форматов данных:

REST часто использует форматы данных, такие как JSON (JavaScript Object Notation) или XML (Extensible Markup Language), которые легче читать и парсить для различных языков программирования. SOAP, с другой стороны, часто использует XML, который может быть более громоздким и менее удобным для работы.

Гибкость и масштабируемость:

REST предоставляет более гибкий подход к созданию веб-сервисов, позволяя использовать различные HTTP методы для выполнения операций (например, GET для чтения данных, POST для создания данных, PUT для обновления данных, DELETE для удаления данных). Это делает REST более масштабируемым и адаптивным к различным потребностям.

Легкая связь между клиентом и сервером:

REST поддерживает принципы кэширования, асинхронного обмена данными и отсутствия состояния (statelessness), что упрощает разработку и обеспечивает более простую связь между клиентом и сервером. Клиент может сохранять данные кэша для повторного использования, а сервер может быть построен как набор независимых сервисов (микросервисы).

Следующим постом рассмотрим пример сравнения использования REST и SOAP
4👍1👀1
Пример сравнения использования REST и SOAP для создания веб-сервиса получения информации о пользователе:

RESTful сервис:


GET /api/users/123 HTTP/1.1
Host: example.com
Accept: application/json


HTTP/1.1 200 OK
Content-Type: application/json

{
"id": 123,
"name": "John Doe",
"email": "[email protected]"
}


SOAP сервис:


POST /UserService HTTP/1.1
Host: example.com
Content-Type: text/xml; charset=utf-8
Content-Length: 250

<soap:Envelope xmlns:soap="https://www.w3.org/2003/05/soap-envelope" xmlns:ns="https://example.com/">
<soap:Header/>
<soap:Body>
<ns:GetUserInfo>
<ns:UserID>123</ns:UserID>
</ns:GetUserInfo>
</soap:Body>
</soap:Envelope>


HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8

<soap:Envelope xmlns:soap="https://www.w3.org/2003/05/soap-envelope" xmlns:ns="https://example.com/">
<soap:Header/>
<soap:Body>
<ns:GetUserInfoResponse>
<ns:UserName>John Doe</ns:UserName>
<ns:Email>[email protected]</ns:Email>
</ns:GetUserInfoResponse>
</soap:Body>
</soap:Envelope>


Из примеров видно, что REST использует простые HTTP запросы (GET) для получения данных в формате JSON, тогда как SOAP требует отправки специально сформированных XML-запросов и обработки XML-ответов. REST обеспечивает более прямую и понятную модель взаимодействия, что делает его популярным выбором для создания современных веб-сервисов.
👍2👀1
Что такое Маршалинг и чем он отличается от Сериализации максимально содержательно и с примерами

Маршалинг (Marshalling) и сериализация (Serialization)
- это процессы преобразования данных из структурированного формата (например, объекты в памяти) в формат, который может быть передан или сохранен (например, в виде байтового потока), и наоборот. Оба термина часто используются в контексте передачи данных между различными приложениями или процессами.

Маршалинг (Marshalling):


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

import pickle

import json

# Преобразование объекта Python в JSON-строку (маршалинг)
data = {'name': 'John', 'age': 30, 'city': 'New York'}
json_string = json.dumps(data)
print(json_string)


Здесь объект data (словарь Python) маршализуется в JSON-строку с помощью функции json.dumps(). Результатом будет строка {"name": "John", "age": 30, "city": "New York"}.

Сериализация (Serialization):


Сериализация подразумевает преобразование данных в формат, который может быть сохранен в файле или передан через сеть, чтобы потом быть восстановленным в исходное состояние. Сериализация часто используется для сохранения состояния объектов или передачи структурированных данных между различными приложениями или устройствами.

import pickle

# Сериализация объекта Python в бинарный формат (pickle)
data = {'name': 'Alice', 'age': 25, 'city': 'Los Angeles'}
with open('data.pkl', 'wb') as f:
pickle.dump(data, f)


Здесь объект data (словарь Python) сериализуется в бинарный формат с помощью модуля pickle и сохраняется в файл data.pkl.

Отличия между Маршалингом и Сериализацией:


• Формат вывода: Маршалинг чаще всего приводит к преобразованию данных в текстовый формат (например, JSON), который читаем человеком. Сериализация может быть бинарной или текстовой и предназначена для сохранения данных или передачи между системами.

• Цель использования: Маршалинг чаще всего используется для передачи данных через сеть или взаимодействия между различными приложениями. Сериализация чаще всего используется для сохранения состояния объектов или данных в файлы.

• Используемые форматы: Маршалинг часто осуществляется в формате, понятном различным системам (например, JSON для веб-сервисов). Сериализация может быть более специфичной и привязанной к определенному формату (например, использование pickle для сериализации объектов Python).

В целом, маршалинг и сериализация представляют собой важные процессы для обмена и сохранения данных в программировании, и различаются преимущественно по форматам вывода и целям использования.
5👍4🤯1
Задача: Сделать конвейер чисел

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

Довольно частая задача, более подробно можно почитать тут: https://blog.golang.org/pipelines


Решается довольно прямолинейно — запускаем две горутины. В одной пишем в первый канал. Во второй читаем из первого канала и пишем во второй. Главное — не забыть закрыть каналы, чтобы ничего нигде не заблокировалось.

Как всегда, решение закину следующим постом👇