Работа над дизайном функции электронной коммерции
Работа над дизайном функции электронной коммерции

Вроде сначала, а потом читай, Java продвинута более чем наполовину.

В интервью по проектированию системы Google есть вопрос о том, как спроектировать архитектуру флэш-продаж.,ИностранецБратданный5метод,На фото ниже один из них.

Меня зовут брат Нэн, я думаю, вам будет полезно пройти собеседование и получить предложение.

Постучите по доске: Интервьюер спросит вас о следующем функциональном дизайне!

  1. Как вы спроектировали таблицу базы данных?
  2. Как обеспечить удобство использования интерфейса списка товаров?
  3. Почему сведения о продукте необходимо кэшировать?
  4. Как обеспечить безопасность логики размещения заказов?
  5. Как бы вы разработали функцию флэш-распродажи?

Я давно хотел написать такую ​​статью о функциональном дизайне продукта, и за последние несколько дней я заполнил пробелы, чтобы дать друзьям ссылку на «основные моменты проекта».

1. Дизайн функции электронной коммерции

1.1 Дизайн таблицы продуктов

Интервьюер: Как вы спроектировали таблицу базы данных?

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

(1) Список продуктов

Язык кода:sql
копировать
CREATE TABLE products (
    product_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    price DECIMAL(10, 2) NOT NULL,
    stock INT DEFAULT 0,
    category_id INT,
    status ENUM('active', 'inactive', 'deleted') DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (category_id) REFERENCES product_categories(category_id)
);

(2) Таблица классификации продукции

Язык кода:sql
копировать
CREATE TABLE product_categories (
    category_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    parent_id INT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (parent_id) REFERENCES product_categories(category_id)
);

(3) Таблица корзины покупок пользователя

Язык кода:sql
копировать
CREATE TABLE shopping_carts (
    cart_id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    product_id INT NOT NULL,
    quantity INT DEFAULT 1,
    added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(user_id),
    FOREIGN KEY (product_id) REFERENCES products(product_id)
);

(4) Форма заказа

Язык кода:sql
копировать
CREATE TABLE orders (
    order_id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    total_price DECIMAL(10, 2) NOT NULL,
    status ENUM('pending', 'completed', 'cancelled') DEFAULT 'pending',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(user_id)
);

1.2 Список продуктов

Интервьюер: Как обеспечить удобство использования интерфейса списка товаров?

В приложениях электронной коммерции существует множество форм списков продуктов, например: списки популярных продуктов, списки продуктов с условиями запроса и списки рекомендованных пользователем продуктов.

(1) Список популярных продуктов

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

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

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

Язык кода:java
копировать
// Распределенный кеш обновляется при настройке популярных товаров в фоновом режиме, а популярный Список Интерфейс продуктов напрямую запрашивает Redis
public List<Product> getHotProductList() {
    // Получить популярный Список из кеша Redis продуктов
    List<Product> hotProducts = redisTemplate.opsForList().range("hot_products", 0, -1);
    if (hotProducts == null || hotProducts.isEmpty()) {
        // Если кеш пуст, выполните запрос из базы данных и обновите кеш.
        hotProducts = productService.fetchHotProductsFromDB();
        redisTemplate.opsForList().rightPushAll("hot_products", hotProducts);
    }
    return hotProducts;
}

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

(2) Список продуктов по условиям запроса

Условия запросов пользователей разнообразны. Мы можем записывать ключевые слова запроса пользователя через скрытые точки и просить операцию предоставить наиболее популярные ключевые слова запроса продукта.

Поиск по популярным ключевым словам,Кэшировать результаты запроса. Конечно, весь результат запроса будет очень большим.,Мы установилипервые несколько страницКэширование。

Где находится кэш?

Здесь мы все равно помещаем его в распределенный кеш Redis. Кто-то может сказать, поместите это в локальный кэш бэкэнда? Возможно, он не сталкивался с недостатками кэшей первого и второго уровня MyBatis. Кэш первого уровня MyBatis действует на объект SqlSession, а кэш второго уровня — на объект Mapper. Это приводит к тому, что у каждой серверной службы создаются разные локальные кэши, а результаты каждого запроса различны.

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

Язык кода:java
копировать
// Условия запроса Список продуктов
public List<Product> getProductsByQuery(String query, int page) {
    String cacheKey = "query_products:" + query + ":page" + page;
    List<Product> products = redisTemplate.opsForList().range(cacheKey, 0, -1);
    if (products == null || products.isEmpty()) {
        // Если кеш пуст, выполните запрос из базы данных и обновите кеш.
        products = productService.fetchProductsByQueryFromDB(query, page);
        redisTemplate.opsForList().rightPushAll(cacheKey, products);
        // Кэш действителен в течение 10 минут.
        redisTemplate.expire(cacheKey, 10, TimeUnit.MINUTES);
    }
    return products;
}

Еще вопрос, что делать, если результаты запроса изменятся?

Здесь мы настраиваем запланированную задачу для периодического обновления кэшированных результатов «списка продуктов по условиям запроса».

Язык кода:java
копировать
// Кэш обновлений запланированных задач
@Scheduled(fixedRate = 600000)
public void updateProductsCache() {
    // Повторно получить данные из базы данных и обновить кеш
    List<String> hotQueries = analyticsService.getHotQueries();
    for (String query : hotQueries) {
        List<Product> products = productService.fetchProductsByQueryFromDB(query, 1); // Только пример: обновить первую страницу данных.
        String cacheKey = "query_products:" + query + ":page1";
        redisTemplate.delete(cacheKey);
        redisTemplate.opsForList().rightPushAll(cacheKey, products);
         // Сбросить срок действия кэша
        redisTemplate.expire(cacheKey, 10, TimeUnit.MINUTES);
    }
}

1.3 Подробности о продукте

Интервьюер: Почему сведения о продукте необходимо кэшировать?

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

Угадайте, что они делают, пользователи неоднократно сравнивают разные товары, чтобы убедить себя, какой купить. Ведь обсессивно-компульсивное расстройство есть у каждого.

Основываясь на вышеуказанном поведении пользователя и характеристиках сведений о продукте, мы можем кэшировать сведения о продукте в приложении.

1.4 Заказ продукции

Интервьюер: Как обеспечить безопасность логики размещения заказов?

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

(1) Функция проверки

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

  1. Проверка личности пользователя
  2. Проверка баланса пользователя
  3. Проверка продукта
  4. Проверка наличия товара

(2) Предотвращение дублирования заявок

Кроме того, необходимо добавить ограничения на повторную отправку в интерфейс заказа. Здесь доступно множество решений. Например, при использовании решения распределенной блокировки Redis параметр ключа распределенной блокировки Redis связан с идентификатором пользователя и продукта.

Язык кода:sql
копировать
# Ключ распределенной блокировки Redis
lock:order:{uid}:{product_id}

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

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

(3) Контроль транзакций

Весь процесс заказа, включая сокращение запасов, вычеты пользователей и создание таблицы заказов, должен быть включен в одну транзакцию MySQL. Если какая-либо логика в процессе пойдет не так, она будет отменена.

(4) Асинхронная обработка

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

Язык кода:java
копировать
// Пользовательский интерфейс заказа
public Order placeOrder(int userId, int productId, int quantity) throws Exception {
    // Получить распределенную блокировку
    String lockKey = "lock:order:" + userId + ":" + productId;
    if (!redisTemplate.opsForValue().setIfAbsent(lockKey, "locked", 10, TimeUnit.SECONDS)) {
        throw new Exception("Заказы размещаются слишком часто, повторите попытку позже");
    }

    try {
        // Проверьте пользователей, продукты и инвентарь
        userService.verifyUser(userId);
        Product product = productService.verifyProduct(productId);
        inventoryService.checkInventory(productId, quantity);

        // начать транзакцию
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());

        try {
            // Сокращайте запасы, вычитайте комиссии и генерируйте заказы
            inventoryService.decreaseInventory(productId, quantity);
            userService.debitUserAccount(userId, product.getPrice().multiply(new BigDecimal(quantity)));
            Order order = orderService.createOrder(userId, productId, product.getPrice(), quantity);
            
            transactionManager.commit(status); // совершить транзакцию
            return order;
        } catch (Exception e) {
            transactionManager.rollback(status); // Откат транзакции
            throw e;
        }
    } finally {
        redisTemplate.delete(lockKey); // разблокировать замок
    }
}

1.5 Фокус: Flash-продажи

Интервьюер: Как бы вы разработали функцию мгновенной продажи?

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

Основываясь на приведенной выше простой сортировке, мы можем спроектировать ее, чтобы обеспечить стабильность сцены флэш-продажи.

(1) Статическая флэш-страница продажи

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

(2) Ограничения заказа

Первоначальные проекты многих программистов включают все запросы в процесс заказа интерфейса.,Совершенно ненужно! ! !

Если количество флэш-продаж составляет всего 10, мы можем настроить перехват фильтрации перед интерфейсом заказа. Только первые 50 пользователей войдут в процесс заказа, а запросы других пользователей на заказ будут даже не отклонены. пройти процедуру заказа.

Впоследствии эти 50 пользователей захватят эти 10 товарных запасов.

Язык кода:java
копировать
// Решите, разрешать ли пользователям участвовать в процессе срочной покупки.
public class SeckillController {

    @Autowired
    private KafkaTemplate<String, SeckillOrderRequest> kafkaTemplate;

    public ResponseEntity<String> placeSeckillOrder(int userId, int productId) {
        String queueName = "seckill_orders";
        String lockKey = "seckill:availability:" + productId;
        // Проверьте, имеете ли вы право на флэш-распродажу
        Long rank = redisTemplate.opsForValue().increment(lockKey);
        if (rank == null || rank > 50) {
            return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body("К сожалению, квота флэш-продажи заполнена.");
        }

        // Создать запрос на флэш-продажу
        SeckillOrderRequest request = new SeckillOrderRequest(userId, productId);

        // Отправить в очередь Kafka
        kafkaTemplate.send(queueName, request);
        return ResponseEntity.ok("Ваш запрос на продажу флэш-памяти получен и обрабатывается. Пожалуйста, терпеливо ждите результата.");
    }
}

(3) Запрос заказа на основе задачи

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

Язык кода:java
копировать
// Выйдите и разместите задачу в очереди заказов
@Service
public class SeckillOrderConsumer {

    @Autowired
    private OrderService orderService;

    @Autowired
    private ProductService productService;

    @Autowired
    private InventoryService inventoryService;

    @KafkaListener(topics = "seckill_orders", groupId = "seckill_group")
    public void consume(SeckillOrderRequest request) {
        try {
            // Проверить инвентарь
            if (!inventoryService.checkInventory(request.getProductId(), 1)) {
                throw new Exception("Недостаточно запасов");
            }
            // Обработка заказа
            Order order = orderService.createSeckillOrder(request.getUserId(), request.getProductId(), 1);
            // Другая логическая обработка
            notifyUser(order);
        } catch (Exception e) {
            // Обработка логики ошибок
            System.out.println("Не удалось обработать флэш-продажу:" + e.getMessage());
        }
    }

    private void notifyUser(Order order) {
        // Уведомляйте пользователей о результатах флэш-распродажи
    }
}

Я Брат Нэн, Нэн - это Нэн. Мне нравятся ваши лайки, лайки и лайки на Get.

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

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose