B.30.01.1-Java并發編程及電商場景應用

摘要

本文深入探討了Java并發編程的核心概念及其在電商系統中的實際應用。從基礎并發機制到高級并發工具,結合電商業務場景中的典型問題,如高并發秒殺、庫存管理、訂單處理等,提供了實用的解決方案和最佳實踐。

1. Java并發編程基礎

1.1 并發與并行

并發(Concurrency)是指系統能夠處理多個任務的能力,而并行(Parallelism)則是指系統能夠同時執行多個任務。在多核處理器時代,Java通過線程實現了真正的并行計算。

1.2 Java內存模型(JMM)

Java內存模型定義了線程如何與主內存以及彼此的工作內存進行交互。JMM解決了可見性、原子性和有序性問題,為并發編程提供了基礎保障。

public class VisibilityExample {private boolean flag = false;public void writer() {flag = true; // 線程A執行}public void reader() {if (flag) { // 線程B執行System.out.println("Flag is true");}}
}

在上述代碼中,如果沒有適當的同步機制,線程A對flag的修改可能對線程B不可見。

1.3 synchronized與volatile

  • synchronized:保證原子性和可見性,通過管程(Monitor)實現
  • volatile:保證可見性和有序性,但不保證原子性
public class Counter {private volatile int count = 0;public synchronized void increment() {count++; // 復合操作,需要synchronized保證原子性}public int getCount() {return count; // volatile保證可見性}
}

2. Java并發工具類

2.1 線程池(ThreadPoolExecutor)

線程池通過重用線程降低了線程創建和銷毀的開銷,提高了系統響應速度。

ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,    // 核心線程數maximumPoolSize, // 最大線程數keepAliveTime,   // 空閑線程存活時間TimeUnit.SECONDS,new LinkedBlockingQueue<>(1000), // 任務隊列new ThreadPoolExecutor.CallerRunsPolicy() // 拒絕策略
);

2.2 并發集合

  • ConcurrentHashMap:線程安全的HashMap實現,采用分段鎖或CAS機制
  • CopyOnWriteArrayList:寫時復制,適合讀多寫少的場景
  • BlockingQueue:阻塞隊列,用于生產者-消費者模式

2.3 同步工具類

  • CountDownLatch:允許一個或多個線程等待其他線程完成操作
  • CyclicBarrier:讓一組線程到達一個屏障時被阻塞,直到最后一個線程到達時才放開
  • Semaphore:控制同時訪問資源的線程數量

3. 電商場景中的并發應用

3.1 高并發秒殺系統

秒殺系統是電商場景中典型的并發挑戰,需要解決超賣、性能瓶頸等問題。

3.1.1 樂觀鎖實現
public class SeckillService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;public boolean seckill(Long productId, Long userId) {// 使用Redis的原子操作String key = "seckill:product:" + productId;// 監視商品庫存redisTemplate.watch(key);int stock = (int) redisTemplate.opsForValue().get(key);if (stock <= 0) {redisTemplate.unwatch();return false;}// 開啟事務redisTemplate.multi();redisTemplate.opsForValue().decrement(key);redisTemplate.opsForList().rightPush("seckill:user:" + productId, userId);// 執行事務List<Object> exec = redisTemplate.exec();if (exec == null || exec.isEmpty()) {// 事務執行失敗,可能是庫存已被其他線程修改return false;}return true;}
}
3.1.2 令牌桶限流
public class RateLimiter {private final int maxTokens;private final int refillRate;private int currentTokens;private long lastRefillTimestamp;public synchronized boolean tryAcquire() {refill();if (currentTokens > 0) {currentTokens--;return true;}return false;}private void refill() {long now = System.currentTimeMillis();long elapsedTime = now - lastRefillTimestamp;int tokensToAdd = (int) (elapsedTime * refillRate / 1000);if (tokensToAdd > 0) {currentTokens = Math.min(maxTokens, currentTokens + tokensToAdd);lastRefillTimestamp = now;}}
}

3.2 庫存管理系統

庫存管理需要保證數據一致性,防止超賣和少賣。

3.2.1 分布式鎖實現
public class DistributedLock {private final RedisTemplate<String, String> redisTemplate;private final String lockKey;private final String requestId;private final int expireTime;public boolean tryLock() {return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireTime, TimeUnit.MILLISECONDS));}public boolean unlock() {// 使用Lua腳本確保原子性String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +"return redis.call('del', KEYS[1]) " +"else " +"return 0 " +"end";DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);Long result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey), requestId);return result != null && result == 1;}
}
3.2.2 庫存扣減方案
@Service
public class InventoryService {@Autowiredprivate DistributedLockFactory lockFactory;@Transactionalpublic boolean deductInventory(Long productId, int quantity) {String lockKey = "inventory:lock:" + productId;DistributedLock lock = lockFactory.getLock(lockKey);try {if (lock.tryLock(3, TimeUnit.SECONDS)) {// 查詢庫存Inventory inventory = inventoryMapper.selectByProductId(productId);if (inventory == null || inventory.getQuantity() < quantity) {return false;}// 扣減庫存inventory.setQuantity(inventory.getQuantity() - quantity);inventoryMapper.updateById(inventory);// 記錄庫存流水InventoryLog log = new InventoryLog();log.setProductId(productId);log.setQuantity(-quantity);log.setCreateTime(new Date());inventoryLogMapper.insert(log);return true;}return false;} catch (InterruptedException e) {Thread.currentThread().interrupt();return false;} finally {lock.unlock();}}
}

3.3 訂單處理系統

訂單處理涉及多個步驟,需要保證最終一致性。

3.3.1 異步訂單處理
@Service
public class OrderService {@Autowiredprivate ThreadPoolExecutor orderExecutor;@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate PaymentService paymentService;@Autowiredprivate InventoryService inventoryService;public void createOrder(Order order) {// 保存訂單orderMapper.insert(order);// 異步處理訂單orderExecutor.submit(() -> {try {// 扣減庫存boolean deductResult = inventoryService.deductInventory(order.getProductId(), order.getQuantity());if (!deductResult) {// 庫存不足,取消訂單order.setStatus(OrderStatus.CANCELED.getCode());orderMapper.updateById(order);return;}// 調用支付服務boolean payResult = paymentService.processPayment(order.getId(), order.getAmount());if (payResult) {// 支付成功,更新訂單狀態order.setStatus(OrderStatus.PAID.getCode());} else {// 支付失敗,回滾庫存inventoryService.rollbackInventory(order.getProductId(), order.getQuantity());order.setStatus(OrderStatus.PAY_FAILED.getCode());}orderMapper.updateById(order);} catch (Exception e) {// 處理異常,記錄日志log.error("訂單處理異常", e);order.setStatus(OrderStatus.EXCEPTION.getCode());orderMapper.updateById(order);}});}
}
3.3.2 訂單狀態機
public enum OrderStatus {PENDING(1, "待支付"),PAID(2, "已支付"),SHIPPED(3, "已發貨"),COMPLETED(4, "已完成"),CANCELED(5, "已取消"),PAY_FAILED(6, "支付失敗"),EXCEPTION(7, "異常");private final int code;private final String desc;// 狀態轉換規則private static final Map<OrderStatus, Set<OrderStatus>> ALLOWED_TRANSITIONS = new EnumMap<>(OrderStatus.class);static {ALLOWED_TRANSITIONS.put(PENDING, new HashSet<>(Arrays.asList(PAID, CANCELED)));ALLOWED_TRANSITIONS.put(PAID, new HashSet<>(Arrays.asList(SHIPPED, CANCELED)));ALLOWED_TRANSITIONS.put(SHIPPED, new HashSet<>(Collections.singletonList(COMPLETED)));ALLOWED_TRANSITIONS.put(CANCELED, Collections.emptySet());ALLOWED_TRANSITIONS.put(COMPLETED, Collections.emptySet());ALLOWED_TRANSITIONS.put(PAY_FAILED, new HashSet<>(Arrays.asList(PENDING, CANCELED)));ALLOWED_TRANSITIONS.put(EXCEPTION, new HashSet<>(Arrays.asList(PENDING, CANCELED)));}public boolean canTransitionTo(OrderStatus newStatus) {return ALLOWED_TRANSITIONS.get(this).contains(newStatus);}
}

4. 性能優化與最佳實踐

4.1 減少鎖競爭

  • 縮小鎖范圍:只鎖定必要的代碼塊
  • 使用讀寫鎖:讀多寫少場景下提高并發性
  • 分段鎖:如ConcurrentHashMap的實現方式
public class SegmentLockCache<K, V> {private final int segmentCount;private final List<Map<K, V>> segments;private final List<Lock> locks;public SegmentLockCache(int segmentCount) {this.segmentCount = segmentCount;this.segments = new ArrayList<>(segmentCount);this.locks = new ArrayList<>(segmentCount);for (int i = 0; i < segmentCount; i++) {segments.add(new HashMap<>());locks.add(new ReentrantLock());}}public void put(K key, V value) {int segmentIndex = key.hashCode() % segmentCount;Lock lock = locks.get(segmentIndex);Map<K, V> segment = segments.get(segmentIndex);lock.lock();try {segment.put(key, value);} finally {lock.unlock();}}public V get(K key) {int segmentIndex = key.hashCode() % segmentCount;Map<K, V> segment = segments.get(segmentIndex);// 讀操作不加鎖,可能會有臟讀,根據業務場景決定return segment.get(key);}
}

4.2 無鎖編程

使用CAS(Compare-And-Swap)操作實現無鎖算法,提高并發性能。

public class NonBlockingCounter {private final AtomicLong counter = new AtomicLong(0);public void increment() {long oldValue, newValue;do {oldValue = counter.get();newValue = oldValue + 1;} while (!counter.compareAndSet(oldValue, newValue));}public long get() {return counter.get();}
}

4.3 線程池調優

根據業務特點合理配置線程池參數:

// CPU密集型任務
ThreadPoolExecutor cpuIntensiveExecutor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),Runtime.getRuntime().availableProcessors(),60L, TimeUnit.SECONDS,new LinkedBlockingQueue<>()
);
// IO密集型任務
ThreadPoolExecutor ioIntensiveExecutor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2,Runtime.getRuntime().availableProcessors() * 4,60L, TimeUnit.SECONDS,new LinkedBlockingQueue<>(1000),new ThreadPoolExecutor.CallerRunsPolicy()
);

5. 場景清單

場景1:基礎并發概念

請解釋一下Java中的volatile關鍵字和synchronized關鍵字的區別?
回答
volatile和synchronized都是Java中用于實現線程同步的機制,但它們有以下區別:

  1. 功能范圍
    • volatile只能修飾變量,而synchronized可以修飾方法、代碼塊
    • volatile保證變量的可見性和有序性,但不保證原子性
    • synchronized保證原子性、可見性和有序性
  2. 實現機制
    • volatile通過內存屏障和禁止指令重排序實現
    • synchronized通過管程(Monitor)機制實現,涉及對象頭的Mark Word
  3. 性能影響
    • volatile不會引起線程上下文切換,性能開銷較小
    • synchronized可能引起線程阻塞和上下文切換,性能開銷較大
  4. 使用場景
    • volatile適用于一個線程寫,多個線程讀的場景
    • synchronized適用于復合操作或需要保證原子性的場景
      在實際應用中,我會根據具體需求選擇合適的同步機制。例如,在電商秒殺系統中,對于商品庫存這種需要保證原子性的操作,我會使用synchronized或分布式鎖;而對于狀態標志位這種簡單變量,我會使用volatile。

場景2:線程池應用

在電商系統中,如何合理配置線程池參數?如果遇到任務堆積和拒絕任務的情況,你會如何處理?
回答
在電商系統中配置線程池參數需要考慮以下幾個因素:

  1. 核心參數配置
    • 核心線程數(corePoolSize):對于CPU密集型任務,設置為CPU核心數;對于IO密集型任務,設置為CPU核心數的2倍左右
    • 最大線程數(maximumPoolSize):考慮系統資源限制和業務峰值,通常設置為核心線程數的2-4倍
    • 隊列容量:根據系統內存和任務處理速度設置,避免OOM
    • 線程存活時間(keepAliveTime):根據業務波峰波谷特點設置,通常30秒到幾分鐘
  2. 拒絕策略選擇
    • AbortPolicy:直接拋出異常,適合關鍵業務
    • CallerRunsPolicy:由提交任務的線程執行,適合非關鍵業務
    • DiscardOldestPolicy:丟棄隊列中最老的任務,適合可容忍任務丟失的場景
    • DiscardPolicy:直接丟棄任務,適合可容忍任務丟失的場景
  3. 任務堆積處理
    • 監控線程池隊列大小和活躍線程數,設置告警閾值
    • 實現動態調整線程池參數的能力,應對流量高峰
    • 對于長時間運行的任務,設置超時機制
    • 考慮使用異步+回調方式,避免阻塞線程
      在實際項目中,我會這樣處理電商訂單處理線程池:
// 訂單處理線程池配置
ThreadPoolExecutor orderExecutor = new ThreadPoolExecutor(10, // 核心線程數50, // 最大線程數60, // 空閑線程存活時間(秒)TimeUnit.SECONDS,new LinkedBlockingQueue<>(1000), // 任務隊列new ThreadFactoryBuilder().setNameFormat("order-pool-%d").build(),new ThreadPoolExecutor.CallerRunsPolicy() // 拒絕策略
);
// 監控線程池狀態
ScheduledExecutorService monitorExecutor = Executors.newSingleThreadScheduledExecutor();
monitorExecutor.scheduleAtFixedRate(() -> {int activeCount = orderExecutor.getActiveCount();int queueSize = orderExecutor.getQueue().size();long completedTaskCount = orderExecutor.getCompletedTaskCount();// 記錄監控指標log.info("OrderPool Stats: active={}, queue={}, completed={}", activeCount, queueSize, completedTaskCount);// 如果隊列堆積超過閾值,可以觸發告警或動態調整參數if (queueSize > 800) {log.warn("OrderPool queue size exceeds threshold: {}", queueSize);// 可以觸發告警或動態調整參數}
}, 0, 1, TimeUnit.MINUTES);

場景3:高并發秒殺系統設計

請設計一個高并發的秒殺系統,需要考慮哪些關鍵點?如何防止超賣?
回答
設計高并發秒殺系統需要考慮以下幾個關鍵點:

  1. 系統架構設計
    • 前端:頁面靜態化,CDN加速,按鈕防重復提交
    • 網關層:限流、熔斷、緩存
    • 服務層:服務拆分,異步處理
    • 數據層:讀寫分離,分庫分表
  2. 防止超賣方案
    • 數據庫層面:使用樂觀鎖或悲觀鎖
      -- 樂觀鎖更新
      UPDATE product SET stock = stock - 1, version = version + 1 
      WHERE id = #{productId} AND stock > 0 AND version = #{version}
      
    • Redis層面:使用Redis原子操作
      // Lua腳本保證原子性
      String script = "local stock = redis.call('get', KEYS[1]) " +"if tonumber(stock) > 0 then " +"    redis.call('decr', KEYS[1]) " +"    return 1 " +"else " +"    return 0 " +"end";
      
    • 消息隊列:將請求放入消息隊列,按順序處理
  3. 限流措施
    • 接口限流:使用令牌桶或漏桶算法
    • 用戶限流:限制單個用戶的請求頻率
    • 總體限流:系統級別的流量控制
  4. 緩存策略
    • 商品信息緩存:提前加載到Redis
    • 庫存緩存:使用Redis存儲庫存
    • 本地緩存:熱點數據本地緩存
  5. 異步處理
    • 下單請求先落庫,狀態為處理中
    • 異步校驗庫存、扣減庫存
    • 成功后更新訂單狀態,失敗則回滾
      實際代碼實現示例:
@Service
public class SeckillService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowiredprivate RabbitTemplate rabbitTemplate;@Autowiredprivate ProductMapper productMapper;@Autowiredprivate OrderMapper orderMapper;// 秒殺請求入口public boolean seckill(Long productId, Long userId) {// 1. 限流檢查if (!rateLimiter.tryAcquire()) {throw new BusinessException("系統繁忙,請稍后再試");}// 2. 用戶限流檢查String userKey = "seckill:user:" + userId + ":" + productId;if (redisTemplate.hasKey(userKey)) {throw new BusinessException("不能重復參與秒殺");}redisTemplate.opsForValue().set(userKey, "1", 1, TimeUnit.HOURS);// 3. 預減庫存String stockKey = "seckill:stock:" + productId;Long stock = redisTemplate.opsForValue().decrement(stockKey);if (stock < 0) {// 庫存不足,回滾redisTemplate.opsForValue().increment(stockKey);throw new BusinessException("商品已售罄");}// 4. 創建訂單(狀態為處理中)Order order = new Order();order.setProductId(productId);order.setUserId(userId);order.setStatus(OrderStatus.PROCESSING.getCode());order.setCreateTime(new Date());orderMapper.insert(order);// 5. 發送消息到MQ進行異步處理rabbitTemplate.convertAndSend("seckill.order", order);return true;}// 消費者處理訂單@RabbitListener(queues = "seckill.order")public void handleOrder(Order order) {try {// 1. 真正扣減數據庫庫存Product product = productMapper.selectById(order.getProductId());if (product.getStock() <= 0) {// 庫存不足,更新訂單狀態為失敗order.setStatus(OrderStatus.FAILED.getCode());orderMapper.updateById(order);return;}// 使用樂觀鎖扣減庫存int updateCount = productMapper.decreaseStockWithVersion(order.getProductId(), product.getVersion());if (updateCount == 0) {// 版本號不匹配,說明庫存已被其他線程修改order.setStatus(OrderStatus.FAILED.getCode());orderMapper.updateById(order);return;}// 2. 更新訂單狀態為成功order.setStatus(OrderStatus.SUCCESS.getCode());orderMapper.updateById(order);// 3. 發送支付消息rabbitTemplate.convertAndSend("payment.order", order);} catch (Exception e) {log.error("處理秒殺訂單異常", e);// 更新訂單狀態為異常order.setStatus(OrderStatus.EXCEPTION.getCode());orderMapper.updateById(order);}}
}

場景4:分布式事務處理

在電商系統中,下單操作涉及扣減庫存、創建訂單、用戶賬戶扣款等多個步驟,如何保證數據一致性?
回答
在電商系統中,下單操作涉及多個服務的數據一致性,可以采用以下方案:

  1. 分布式事務方案選擇
    • 2PC/3PC:強一致性方案,但性能較差,可用性不高
    • TCC:Try-Confirm-Cancel模式,適用于性能要求高的場景
    • 本地消息表:基于消息隊列的最終一致性方案
    • Saga模式:將長事務拆分為多個本地事務,通過補償機制保證一致性
  2. 電商系統推薦方案
    對于電商下單場景,我推薦采用基于消息隊列的最終一致性方案,結合本地消息表或事務消息。
  3. 具體實現
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate InventoryService inventoryService;@Autowiredprivate AccountService accountService;@Autowiredprivate TransactionTemplate transactionTemplate;@Autowiredprivate RabbitTemplate rabbitTemplate;@Autowiredprivate MessageLogMapper messageLogMapper;// 下單入口public void placeOrder(OrderDTO orderDTO) {// 1. 創建訂單(本地事務)Order order = createOrder(orderDTO);// 2. 發送事務消息sendTransactionMessage(order);}// 創建訂單(本地事務)private Order createOrder(OrderDTO orderDTO) {return transactionTemplate.execute(status -> {// 1. 創建訂單Order order = new Order();BeanUtils.copyProperties(orderDTO, order);order.setStatus(OrderStatus.PENDING_PAYMENT.getCode());order.setCreateTime(new Date());orderMapper.insert(order);// 2. 記錄消息日志(狀態為發送中)MessageLog messageLog = new MessageLog();messageLog.setMessageId(UUID.randomUUID().toString());messageLog.setMessage(JSON.toJSONString(order));messageLog.setStatus(MessageStatus.SENDING.getCode());messageLog.setCreateTime(new Date());messageLogMapper.insert(messageLog);return order;});}// 發送事務消息private void sendTransactionMessage(Order order) {// 1. 發送消息到MQrabbitTemplate.convertAndSend("order.process", order);// 2. 更新消息狀態為已發送messageLogMapper.updateStatusByMessageId(order.getMessageId(), MessageStatus.SENT.getCode());}// 消息消費者處理訂單@RabbitListener(queues = "order.process")public void processOrder(Order order) {try {// 1. 扣減庫存boolean inventoryResult = inventoryService.deductInventory(order.getProductId(), order.getQuantity());if (!inventoryResult) {// 庫存不足,取消訂單cancelOrder(order, "庫存不足");return;}// 2. 扣減用戶賬戶boolean accountResult = accountService.deductBalance(order.getUserId(), order.getAmount());if (!accountResult) {// 賬戶余額不足,回滾庫存并取消訂單inventoryService.rollbackInventory(order.getProductId(), order.getQuantity());cancelOrder(order, "賬戶余額不足");return;}// 3. 更新訂單狀態為已完成order.setStatus(OrderStatus.COMPLETED.getCode());orderMapper.updateById(order);// 4. 更新消息狀態為已處理messageLogMapper.updateStatusByMessageId(order.getMessageId(), MessageStatus.PROCESSED.getCode());} catch (Exception e) {log.error("處理訂單異常", e);// 處理失敗,等待重試}}// 取消訂單private void cancelOrder(Order order, String reason) {order.setStatus(OrderStatus.CANCELED.getCode());order.setCancelReason(reason);orderMapper.updateById(order);// 更新消息狀態為已處理messageLogMapper.updateStatusByMessageId(order.getMessageId(), MessageStatus.PROCESSED.getCode());}// 定時任務補償處理@Scheduled(fixedDelay = 60000)public void compensateMessages() {// 查詢發送中的消息List<MessageLog> messageLogs = messageLogMapper.selectByStatus(MessageStatus.SENDING.getCode());for (MessageLog messageLog : messageLogs) {try {// 重新發送消息Order order = JSON.parseObject(messageLog.getMessage(), Order.class);rabbitTemplate.convertAndSend("order.process", order);// 更新消息狀態為已發送messageLogMapper.updateStatusByMessageId(messageLog.getMessageId(), MessageStatus.SENT.getCode());} catch (Exception e) {log.error("補償消息發送失敗", e);}}// 查詢已發送但未處理的消息List<MessageLog> sentMessages = messageLogMapper.selectByStatus(MessageStatus.SENT.getCode());for (MessageLog messageLog : sentMessages) {// 檢查消息是否超時(如5分鐘)if (System.currentTimeMillis() - messageLog.getCreateTime().getTime() > 5 * 60 * 1000) {try {Order order = JSON.parseObject(messageLog.getMessage(), Order.class);// 回滾操作inventoryService.rollbackInventory(order.getProductId(), order.getQuantity());// 取消訂單cancelOrder(order, "訂單處理超時");// 更新消息狀態為已處理messageLogMapper.updateStatusByMessageId(messageLog.getMessageId(), MessageStatus.PROCESSED.getCode());} catch (Exception e) {log.error("超時消息處理失敗", e);}}}}
}
  1. 可靠性保障
    • 消息持久化:確保消息不丟失
    • 消息確認機制:消費者確認處理成功
    • 重試機制:失敗后自動重試
    • 補償機制:定時任務檢查并補償未處理的消息
    • 冪等性設計:防止重復處理導致的數據不一致
  2. 監控與告警
    • 監控消息堆積情況
    • 監控事務處理成功率
    • 設置異常告警機制
      這種方案實現了最終一致性,在保證業務連續性的同時,提供了較好的性能和可用性。在實際應用中,還可以結合分布式事務框架如Seata來簡化實現。

6. 總結

Java并發編程在電商系統中扮演著至關重要的角色。從基礎的線程安全控制到高級的并發模式應用,合理利用Java并發工具可以顯著提升系統性能和穩定性。在電商場景中,如秒殺、庫存管理、訂單處理等核心業務,都需要精心設計的并發控制機制來保證系統的高可用和數據一致性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/96551.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/96551.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/96551.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

怎樣避免游戲檢測到云手機?

以下是一些可能避免游戲檢測到云手機的方法&#xff1a;云手機可能會因網絡配置等因素出現一些異常網絡行為&#xff0c;如網絡延遲的規律性變化等&#xff0c;在使用云手機玩游戲時&#xff0c;盡量保持網絡行為的穩定性和自然性&#xff0c;避免短時間內頻繁切換網絡連接&…

文件上傳 --- uploadlabs靶場

目錄 1 前端和js校驗 抓包改包 2 . 2.1 .htaccess&#xff08;偽靜態&#xff09; 2.2 %00截斷 &#xff08;php5.2&#xff09; 2.3 user_init_ 2.4 3 圖片碼防御 4 競爭型漏洞 思路&#xff1a; 容易出現的問題: 1 前端和js校驗 關閉JS的代碼&#xff0c;上傳PHP…

漢化版本 k6 dashboard

目前官方提供的 dashboard 只有英文版本&#xff0c;國內使用不方便&#xff0c;因此 fork 了下官方倉庫&#xff0c;添加了漢化版本 https://github.com/kinghard7/xk6-dashboardhttps://github.com/kinghard7/xk6-dashboard安裝 xk6 構建程序&#xff1a;go install go.k6.i…

視覺識別:ffmpeg-python、ultralytics.YOLO、OpenCV-Python、標準RTSP地址格式

視覺識別:ffmpeg-python、ultralytics.YOLO、OpenCV-Python、標準RTSP地址格式 ffmpeg-python 核心概念 常用過濾器(Filters) 高級操作 視頻截幀轉換圖片示例 參考 ultralytics.YOLO(You Only Look Once) 1. 模型加載 2. 訓練模型 (`train()`) 標準YAML格式示例 3. 預測 (…

浙江龍庭翔新型建筑材料有限公司全屋定制:暢享品質生活新境界!

在消費升級的時代浪潮中&#xff0c;浙江龍庭翔新型建筑材料有限公司以卓越的產品質量和創新的服務理念&#xff0c;重新定義全屋定制的內涵&#xff0c;為追求高品質生活的消費者打造理想家居。公司秉承"匠心質造&#xff0c;樂享生活"的核心價值觀&#xff0c;將環…

鷹角網絡基于阿里云 EMR Serverless StarRocks 的實時分析工程實踐

一、客戶背景與業務挑戰 1.1 客戶介紹 鷹角網絡&#xff08;HYPERGRYPH&#xff09; 成立于2017年&#xff0c;總部位于上海&#xff0c;是中國知名游戲研發與發行公司&#xff0c;代表產品包括現象級手游《明日方舟》及《泡姆泡姆》《來自星辰》《終末地》等。公司依托阿里云…

LWIP的IP 協議棧

IP 協議棧 下面的分析把上文對 IPv4 概念的說明與 lwIP 中的具體實現代碼對應起來&#xff0c;便于將理論與實現對照理解。分析覆蓋&#xff1a;輸入處理、路由與轉發、輸出與報文構建、分片/重組、校驗和與各種配置點&#xff08;hook、選項、統計等&#xff09;。目錄&#x…

高并發短信網關平臺建設方案概述

本方案涵蓋了架構設計、技術選型、核心功能、高可用保障以及實施路徑,旨在構建一個能夠應對千萬級日吞吐量、穩定、安全、可擴展的現代短信網關平臺。 高并發短信網關平臺建設方案 一、 項目概述與目標 1.1 項目背景 為滿足公司業務(如用戶注冊、登錄、交易驗證、營銷通知…

阿里云服務-開啟對象存儲服務及獲取AccessKey教程

&#xff08;1&#xff09;阿里云OSS簡介 &#xff08;2&#xff09;打開阿里云網址&#xff1a;阿里云登錄 - 歡迎登錄阿里云&#xff0c;安全穩定的云計算服務平臺 點擊“立即開通” &#xff08;2&#xff09;開通成功后&#xff0c;充值任意金額 頂欄選擇“費用”|“充值…

[特殊字符] 高可用高并發微服務架構設計:Nginx 與 API Gateway 的協同實踐

一、Nginx 和 Gateway 的關系&#xff1a;是替代還是協作&#xff1f; 不是替代關系&#xff0c;而是協作關系。 1. Nginx 的角色&#xff08;通常在最外層&#xff09; 反向代理 & 負載均衡&#xff1a;將前端請求分發到多個后端服務或網關實例。 靜態資源服務&#xf…

解碼LLM量化:深入剖析最常見8位與4位核心算法

解碼LLM量化&#xff1a;深入剖析8位與4位核心算法 大型語言模型&#xff08;LLM&#xff09;的性能日益強大&#xff0c;但其龐大的體積和高昂的計算成本構成了部署的主要障礙。模型量化&#xff0c;作為一種將高精度浮點權重&#xff08;如16位&#xff09;映射到低位寬整數&…

提問:溫度不改變 logits 與概率的排名,為何還會影響模型輸出?

你此前圍繞溫度的核心困惑始終是&#xff1a;“溫度不改變 logits 與概率的排名&#xff0c;為何還會影響模型輸出&#xff1f;” 以下總結將緊扣這一困惑&#xff0c;并重點補充核采樣&#xff08;Top-p&#xff09;在其中的作用&#xff0c;明確溫度與核采樣如何共同影響輸出…

【文獻閱讀】Lossless data compression by large models

1. 中華人工智能研究中心&#xff0c;鄭州。 2. 鵬程實驗室&#xff0c;深圳。 3. 上海數學與交叉學科研究所&#xff0c;上海。 4. 中國科學院計算技術研究所&#xff0c;北京。 5. 寧波人工智能產業研究所&#xff0c;寧波。 6. 滑鐵盧大學計算機科學學院&#xff0c;加拿大安…

注意力機制:捕獲長距離依賴關系的革命性技術

本文由「大千AI助手」原創發布&#xff0c;專注用真話講AI&#xff0c;回歸技術本質。拒絕神話或妖魔化。搜索「大千AI助手」關注我&#xff0c;一起撕掉過度包裝&#xff0c;學習真實的AI技術&#xff01; ? 1. 注意力機制概述&#xff1a;為什么需要關注"長距離依賴&qu…

PHP如何使用JpGraph生成柱形圖?

PHP使用JpGraph庫生成各類統計圖形具有顯著優勢&#xff0c;該庫作為專業的PHP圖表生成工具&#xff0c;能夠高效創建包括折線圖、餅圖、散點圖在內的多種數據可視化圖形&#xff0c;其核心價值在于提供了豐富的圖形定制能力和簡潔的API接口。JpGraph通過純PHP實現&#xff0c;…

免費的端口映射工具 ChmlFrp

免費的端口映射工具 ChmlFrp 前言&#xff1a;之前我寫過一篇關于cloudflare tunnel的使用教程&#xff0c;ChmlFrp是一個類似的工具&#xff0c;也可以用來進行內網穿透 我的博客對應文章地址 1.注冊賬號 注冊地址 點擊這個鏈接前往官網注冊一個賬號&#xff0c;過程簡單&…

遙感領域解決方案丨涵蓋:高光譜、無人機多光譜、空天地數據識別與計算

一&#xff1a;AI智慧高光譜遙感實戰&#xff1a;手撕99個案例項目、全覆蓋技術鏈與應用場景一站式提升方案在遙感技術飛速發展的今天&#xff0c;高光譜數據以其獨特的光譜分辨率成為環境監測、精準農業、地質勘探等領域的核心數據源。然而&#xff0c;海量的波段數據、復雜的…

中科米堆CASAIM自動化三維測量設備測量汽車殼體直徑尺寸

隨著新能源汽車產業向輕量化與高集成度發展&#xff0c;殼體作為電池組和電驅系統的核心承載部件&#xff0c;其孔位加工精度直接影響裝配密封性及結構強度&#xff0c;傳統人工測量方式已難以滿足現代化生產需求。自動化三維測量設備的引入&#xff0c;為汽車殼體直徑尺寸測量…

08.21總結

圓方樹 引入 我們注意到&#xff0c;樹結構相比普通圖具有諸多優良特性。若能將在無向圖上求解的問題轉化為樹結構問題&#xff0c;往往能大幅簡化求解過程。圓方樹正是實現這一轉化的有效工具。 定義 我們稱原圖中的點為"圓點"。通過引入方點并調整邊的關系&#xf…

亞馬遜廣告優化新邏輯:從人工苦力到AI智能的進化之路

"為什么我的廣告花費越來越高&#xff0c;轉化卻越來越差&#xff1f;""如何在海量關鍵詞中找到真正能帶來轉化的黃金詞&#xff1f;""為什么手動調整出價總是跟不上流量變化的速度&#xff1f;""怎樣才能避免因庫存問題導致的廣告權重暴跌…