主頁 > 後端開發 > SpringBoot + 秒殺系統

SpringBoot + 秒殺系統

2021-09-17 09:44:03 後端開發

本書原始碼
https://github.com/huangwenyi10/spring-boot-book-v2

目錄

  • 創建
  • 秒殺系統
    • 雛形
      • 小結
      • 詳情
    • 高并發優化
    • 流量削峰

創建


解決 Cannot resolve plugin org.apache.maven.plugins:maven-site-plugin:3.8.2:
https://ld246.com/article/1584103058009

秒殺系統

雛形

原始碼:
https://github.com/13407196713/SpringBoot2

小結

創建資料庫speed-kill-system
三個表 ay_product、ay_user、ay_user_kill_product
分別是用戶、商品、秒殺的商品

model/AyUser
model/AyProduct
model/AyUserKillProduct
model/KillStatus

mysql的依賴和設定
依賴:
application.properties配置:

repository/ProductRepository 商品的增刪改查 CRUD
repository/AyUserKillProductRepository 用戶秒殺商品記錄Repository 增刪查改 CRUD

service/ProductService
service/AyUserKillProductService
service/impl/ProductServiceImpl
service/impl/AyUserKillProductServiceImpl

controller/ProductController

前端依賴和配置
依賴:
application.properties配置:

templates/product_list.html
templates/success.html
templates/fail.html

詳情

創建資料庫speed-kill-system
三個表 ay_product、ay_user、ay_user_kill_product
分別是用戶、商品、秒殺的商品

model/AyUser

// 用戶

// 對物體注釋,任何 Hibernate 映射物件都要有這個注釋
@Entity

// 宣告此物件映射到資料庫的資料表,如果沒有則系統使用默認值(物體的短類名),
@Table(name = "ay_user")

public class AyUser implements Serializable {

    //主鍵
    @Id
    private Integer id;
    //用戶名
    private String name;
    //電話號碼
    private String phoneNumber;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }
    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
}

model/AyProduct

// 商品

@Entity
@Table(name = "ay_product")
public class AyProduct implements Serializable {
    /**
     * 商品id
     */
    @Id
    private Integer id;
    /**
     * 商品圖片
     */
    private String productImg;
    /**
     * 商品名稱
     */
    private String name;
    /**
     * 商品數量
     */
    private Integer number;
    /**
     * 秒殺開始時間
      */
     private Date startTime;
    /**
     * 秒殺結束時間
     */
    private Date endTime;
    /**
     * 創建時間
     */
    private Date createTime;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public Integer getNumber() {
        return number;
    }
    public void setNumber(Integer number) {
        this.number = number;
    }

    public Date getStartTime() {
        return startTime;
    }
    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }

    public Date getEndTime() {
        return endTime;
    }
    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getProductImg() {
        return productImg;
    }
    public void setProductImg(String productImg) {
        this.productImg = productImg;
    }
}

model/AyUserKillProduct

// 秒殺商品

@Entity
@Table(name = "ay_user_kill_product")

public class AyUserKillProduct implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    //指定主鍵的生成策略,有如下四個值 id是主鍵
    // TABLE:使用表保存id值
    // IDENTITY:由資料庫自動生成
    // SEQUENCR :根據底層資料庫的序列來生成主鍵,條件是資料庫支持序列
    // AUTO:主鍵由程式控制

    private Integer id;
    /**
     * 商品id
     */
    private Integer productId;
    /**
     * 用戶id
     */
    private Integer userId;
    /**
     * 狀態,-1:無效;0:成功;1:已付款'
      */
    private Integer state;
    /**
     * 創建時間
     */
    private Date createTime;

    public Integer getProductId() {
        return productId;
    }
    public void setProductId(Integer productId) {
        this.productId = productId;
    }

    public Integer getUserId() {
        return userId;
    }
    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Integer getState() {
        return state;
    }
    public void setState(Integer state) {
        this.state = state;
    }

    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
}

model/KillStatus

// 描述:秒殺狀態類
public enum KillStatus {

    IN_VALID(-1, "無效"),
    SUCCESS(0, "成功"),
    PAY(1,"已付款");


    private int code;
    private String name;

    KillStatus(){}

    KillStatus(int code, String name){
        this.code = code;
        this.name = name;
    }

    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
}

mysql的依賴和設定
依賴:

		<!-- mysql start -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

application.properties配置:

### mysql連接資訊
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/speed-kill-system?serverTimezone=UTC
###用戶名
spring.datasource.username=root
###密碼
spring.datasource.password=123456
###驅動
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

repository/ProductRepository 商品的增刪改查 CRUD

// 商品的增刪改查 CRUD
public interface ProductRepository extends JpaRepository<AyProduct,Integer> {
}

repository/AyUserKillProductRepository 用戶秒殺商品記錄Repository 增刪查改 CRUD

// 描述:用戶秒殺商品記錄Repository 增刪查改 CRUD
public interface AyUserKillProductRepository extends JpaRepository<AyUserKillProduct,Integer> {
}

service/ProductService

public interface ProductService {
    //查詢所有商品
    List<AyProduct> findAll();

    //查詢所有商品
//    Collection<AyProduct> findAllCache();

    // 秒殺商品
    // @param productId 商品id
    // @param userId 用戶id
    AyProduct killProduct(Integer productId, Integer userId);
}

service/AyUserKillProductService

//描述:用戶秒殺商品記錄介面
public interface AyUserKillProductService {
    //保存用戶秒殺商品記錄
    AyUserKillProduct save(AyUserKillProduct killProduct);
}

service/impl/ProductServiceImpl

// 商品服務
@Service
public class ProductServiceImpl implements ProductService {

    @Resource
    private ProductRepository productRepository;

    @Resource
    private AyUserKillProductService ayUserKillProductService;

    //日志
    Logger logger = LoggerFactory.getLogger(ProductServiceImpl.class);

    // 查詢所有商品
    @Override
    public List<AyProduct> findAll() {
        try{
            List<AyProduct> ayProducts = productRepository.findAll();
            return ayProducts;
        }catch (Exception e){
            logger.error("ProductServiceImpl.findAll error", e);
            return Collections.EMPTY_LIST;
        }
    }

    // 秒殺商品
    // @param productId 商品id
    // @param userId 用戶id
    @Override
    public AyProduct killProduct(Integer productId, Integer userId) {
        //查詢商品
        AyProduct ayProduct = productRepository.findById(productId).get();
        //判斷商品是否還有庫存
        if(ayProduct.getNumber() < 0){
            return null;
        }
        //設定商品的庫存:原庫存數量 - 1
        ayProduct.setNumber(ayProduct.getNumber() - 1);
        //更新商品庫存
        ayProduct = productRepository.save(ayProduct);

        //保存商品的秒殺記錄
        AyUserKillProduct killProduct = new AyUserKillProduct();
        killProduct.setCreateTime(new Date());
        killProduct.setProductId(productId);
        killProduct.setUserId(userId);
        //設定秒殺狀態
        killProduct.setState(KillStatus.SUCCESS.getCode());
        //保存秒殺記錄詳細資訊
        ayUserKillProductService.save(killProduct);

        //商品秒殺成功后,更新快取中商品庫存數量
//        redisTemplate.opsForHash().put(KILL_PRODUCT_LIST, killProduct.getProductId(),ayProduct);
        return ayProduct;
    }

}

service/impl/AyUserKillProductServiceImpl

@Service
public class AyUserKillProductServiceImpl implements AyUserKillProductService {

    @Resource
    private AyUserKillProductRepository ayUserKillProductRepository;

    //保存用戶秒殺商品記錄
    //@param killProduct
    @Override
    public AyUserKillProduct save(AyUserKillProduct killProduct) {
        return ayUserKillProductRepository.save(killProduct);
    }
}

controller/ProductController

@Controller
@RequestMapping("/products")
public class ProductController {

    @Resource
    private ProductService productService;

    //查詢所有的商品
    @RequestMapping("/all")
    public String findAll(Model model){
        List<AyProduct> products = productService.findAll();
        model.addAttribute("products", products);
        return "product_list";
    }

    // 秒殺商品
    @RequestMapping("/{id}/kill")
    public String killProduct(Model model,
                              @PathVariable("id") Integer productId,
                              @RequestParam("userId") Integer userId){
        AyProduct ayProduct = productService.killProduct(productId, userId);
        if(null != ayProduct){
            return "success";
        }
        return "fail";
    }
}

前端依賴和配置
依賴:

	<!-- thymeleaf -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
        <version>2.3.4.RELEASE</version>
    </dependency>

application.properties配置:

#thymeleaf配置
#模板的模式,支持如:HTML、XML、TEXT、JAVASCRIPT等
spring.thymeleaf.mode=HTML5
#編碼,可不用配置
spring.thymeleaf.encoding=UTF-8
#內容類別,可不用配置
spring.thymeleaf.servlet.content-type=text/html
#開發配置為false,避免修改模板還要重啟服務器
spring.thymeleaf.cache=false
#配置模板路徑,默認就是templates,可不用配置
#spring.thymeleaf.prefix=classpath:/templates/

templates/product_list.html

<!DOCTYPE HTML>

<html xmlns:th="http://www.thymeleaf.org">

<head>
    <title>hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <!-- 引入 Bootstrap -->
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>

<!-- 頁面顯示部分-->
<div class="container">
    <div class="panel panel-default">
        <div class="panel-heading text-center">
            <h1>秒殺活動</h1>
        </div>
        <div class="panel-body">
            <table class="table table-hover">
                <thead>
                <tr>
                    <td>圖片</td>
                    <td>名稱</td>
                    <td>庫存</td>
                    <td>開始時間</td>
                    <td>結束時間</td>
                    <td>操作</td>
                </tr>
                </thead>

                <tbody>
                <tr th:each="product:${products}">
                    <td>
                        <img border="1px" width="100px" height="110px" th:src="@{${product.productImg}}"/>
                    </td>
                    <td th:text="${product.name}"></td>
                    <td th:text="${product.number}"></td>
                    <td th:text="${product.startTime}"></td>
                    <td th:text="${product.endTime}"></td>
                    <td>
                        <!-- 發起秒殺請求,用戶id先簡單寫死為 1 -->
                        <a class="btn btn-info" th:href="@{'/products/'+${product.id} + '/kill' + '?userId=1'}">秒殺</a>

                    </td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

</body>
<!-- jQuery檔案,務必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 檔案 -->
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</html>

templates/success.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div align="center">
    客官!!! 恭喜您,秒殺成功~~~
</div>
</body>
</html>

templates/fail.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div align="center">
    不要灰心,繼續加油~~~
</div>
</body>

</html>

啟動 SpringBoot2Application
進入 http://localhost:8080/products/all


高并發優化

原始碼
https://github.com/13407196713/SpringBoot2_2

引入redis快取
application.properties

### redis快取配置
### 默認redis資料庫為db0
spring.redis.database=0
### 服務器地址,默認為localhost
spring.redis.host=localhost
### 鏈接埠,默認為6379
spring.redis.port=6379
### redis密碼默認為空
spring.redis.password=
spring.redis.timeout=10000

service/ProductService

	//查詢所有商品
	Collection<AyProduct> findAllCache();

service/impl/ProductServiceImpl


	//注入redisTemplate物件
    @Resource
    private RedisTemplate redisTemplate;
    //定義快取key
    private static final String KILL_PRODUCT_LIST = "kill_product_list";

    //查詢商品資料(帶快取)
    @Override
    public Collection<AyProduct> findAllCache() {
        try{
            //從快取中查詢商品資料
            Map<Integer, AyProduct> productMap = redisTemplate.opsForHash().entries(KILL_PRODUCT_LIST);
            Collection<AyProduct> ayProducts = null;
            //如果快取中查詢不到商品資料
            if(CollectionUtils.isEmpty(productMap)){
                //從資料庫中查詢商品資料
                ayProducts = productRepository.findAll();
                //將商品list轉換為商品map
                productMap = convertToMap(ayProducts);
                //將商品資料保存到快取中
                redisTemplate.opsForHash().putAll(KILL_PRODUCT_LIST, productMap);
                //設定快取資料的過期時間,這里設定10s,具體時間需要結合業務需求而定
                //如果商品資料變化少,過期時間可以設定長一點;反之,過期時間可以設定短一點
                redisTemplate.expire(KILL_PRODUCT_LIST,10000 , TimeUnit.MILLISECONDS);
                return ayProducts;
            }
            ayProducts = productMap.values();
            return ayProducts;
        }catch (Exception e){
            logger.error("ProductServiceImpl.findAllCache error", e);
            return Collections.EMPTY_LIST;
        }
    }


    //list轉換為map
    private Map<Integer, AyProduct> convertToMap(Collection<AyProduct> ayProducts){
        if(CollectionUtils.isEmpty(ayProducts)){
            return Collections.EMPTY_MAP;
        }
        Map<Integer, AyProduct> productMap = new HashMap<>(ayProducts.size());
        for(AyProduct product: ayProducts){
            productMap.put(product.getId(), product);
        }
        return productMap;
    }

controller/ProductController

    // 查詢所有的商品(快取)
    @RequestMapping("/all/cache")
    public String findAllCache(Model model){
        Collection<AyProduct> products = productService.findAllCache();
        model.addAttribute("products", products);
        return "product_list";
    }

商品秒殺成功后,更新快取中商品庫存數量
service/impl/ProductServiceImpl

        //商品秒殺成功后,更新快取中商品庫存數量
        redisTemplate.opsForHash().put(KILL_PRODUCT_LIST, killProduct.getProductId(),ayProduct);

啟動 redis的redis-server.exe、redis-cli.exe
啟動程式

流量削峰

原始碼
https://github.com/13407196713/SpringBoot2_3

為了讓并發請求更平緩,我們需要流量削峰

用訊息佇列緩沖瞬時流量

ActiveMQ下載安裝
https://blog.csdn.net/weixin_38361347/article/details/83796570

ActiveMQ 依賴

    <!-- activemq start -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-activemq</artifactId>
    </dependency>

配置

### activemq 配置
spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.in-memory=true
spring.activemq.pool.enabled=false
spring.activemq.packages.trust-all=true

生產者
producer/AyProductKillProducer

// 生產者

@Service
public class AyProductKillProducer {

    //日志
    Logger logger = LoggerFactory.getLogger(ProductServiceImpl.class);

    @Resource
    private JmsMessagingTemplate jmsMessagingTemplate;

    /**
     *  描述:發送訊息
     * @param destination 目標地址
     * @param killProduct 描述商品
     */
    public void sendMessage(Destination destination, final AyUserKillProduct killProduct) {
        logger.info("AyProductKillProducer sendMessage , killProduct is" + killProduct);
        jmsMessagingTemplate.convertAndSend(destination, killProduct);
    }
}

消費者
consumer/AyProductKillConsumer

// 消費者
@Component
public class AyProductKillConsumer {

    //日志
    Logger logger = LoggerFactory.getLogger(ProductServiceImpl.class);

    @Resource
    private AyUserKillProductService ayUserKillProductService;

    //消費訊息
    @JmsListener(destination = "ay.queue.asyn.save")
    public void receiveQueue(AyUserKillProduct killProduct){
        //保存秒殺商品資料
        ayUserKillProductService.save(killProduct);
        //記錄日志
        logger.info("ayUserKillProductService save, and killProduct: " + killProduct);
    }
}

修改 service/impl/ProductServiceImpl

@Resource
    private AyProductKillProducer ayProductKillProducer;

    //佇列
    private static Destination destination = new ActiveMQQueue("ay.queue.asyn.save");

    /**
     * 秒殺商品(引入MQ)
     * @param productId 商品id
     * @param userId 用戶id
     */
    @Override
    public AyProduct killProduct(Integer productId, Integer userId) {
        //查詢商品
        AyProduct ayProduct = productRepository.findById(productId).get();
        //判斷商品是否還有庫存
        if(ayProduct.getNumber() < 0){
            return null;
        }
        //設定商品的庫存:原庫存數量 - 1
        ayProduct.setNumber(ayProduct.getNumber() - 1);
        //更新商品庫存
        ayProduct = productRepository.save(ayProduct);
        //保存商品的秒殺記錄
        AyUserKillProduct killProduct = new AyUserKillProduct();
        killProduct.setCreateTime(new Date());
        killProduct.setProductId(productId);
        killProduct.setUserId(userId);
        //設定秒殺狀態
        killProduct.setState(KillStatus.SUCCESS.getCode());
        //保存秒殺記錄詳細資訊
        //ayUserKillProductService.save(killProduct);
        //異步保存商品的秒殺記錄
        ayProductKillProducer.sendMessage(destination, killProduct);

        //商品秒殺成功后,更新快取中商品庫存數量
        redisTemplate.opsForHash().put(KILL_PRODUCT_LIST, killProduct.getProductId(),ayProduct);
        return ayProduct;
    }

啟動 redis的redis-server.exe、redis-cli.exe
啟動apache-activemq 的 bin/win64/activemq
啟動程式

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/300738.html

標籤:java

上一篇:cgb2107-day17

下一篇:【保姆級|建議收藏】阿ken帶你學Java入門及進階(二)——運算子、回圈陳述句,文末有彩蛋鴨???

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more