【Blue Bridge Cup Web】Analysis of real questions for the 13th Blue Bridge Cup Web University Group National Competition in 2022

foreword

For the analysis of the real questions of the provincial competition, see:
Analysis of the real questions of the 13th Blue Bridge Cup Web University Group Provincial Competition in 2022 (full version
)

For more answers to Blue Bridge Cup questions, please refer to the column: Blue Bridge Cup

When I wrote the analysis of the provincial competition before, the length was too long, and the writing was garish, which caused the reading experience of the article to be bad. This time I will not fix those. I will paste the code directly, and the analysis will be written in the code comments. I believe that you can think about it a little bit. Understood, the same, the corresponding 真题代码will share with you:

"Blue Bridge Cup" https://www.aliyundrive.com/s/7fsobhSy8dZ Extraction code: 34pi

If you have a good opinion when reading the article, or find a problem, please leave a lot of comments and discuss with each other

1. One point (5 points)

/**
 * @param {Object} oldArr
 * @param {Object} num
 * */
const splitArray = (oldArr, num) => {
    
    
    // TODO:请补充代码实现功能
    let newArr = [];
    
    // 升序排序后解构赋值深拷贝给oldArr2
    let oldArr2 = [...oldArr.sort((a, b) => a - b)];
    
    const len = oldArr2.length;
    for (let i = 0, j = 0; i < len; i += num, j++) {
    
    
        // splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
        newArr[j] = oldArr2.splice(0, num);
    }

    return newArr;
};
module.exports = splitArray; // 检测需要,请勿删除

2. Fresh vegetables (5 points)

/* TODO:待补充代码 */

#box1 {
    
    
    display: flex;
    justify-content: center;
    align-items: center;
}

#box2,
#box3 {
    
    
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}

#box2 span:nth-child(2),
#box3 span:nth-child(3) {
    
    
    align-self: flex-end;
}

#box3 span:nth-child(2) {
    
    
    align-self: center;
}

3. Fruit Xiaoxiaole (10 points)

// TODO:请补充代码
function startGame() {
    
    
    $("img").show(500);
    $("#start").hide();
    $("img").hide(500);
    // 已经点击的数量
    let i = 0;
    // 存放已经点击的元素
    let clickImg = [];

    [...$(".img-box")].forEach((item) => {
    
    
        item.onclick = function () {
    
    
            i++;
            if (i <= 2) {
    
    
                $(item.children).show();
                clickImg.push(item);

                if (i === 2) {
    
    
                    setTimeout(() => {
    
    
                        let score = $("#score")[0];

                        if (
                            clickImg[0].children[0].alt ===
                            clickImg[1].children[0].alt
                        ) {
    
    
                            score.innerHTML = Number(score.innerHTML) + 2;
                            $(clickImg[0]).css({
    
    
                                // 隐藏元素且保留元素所占位置
                                visibility: "hidden",
                            });
                            $(clickImg[1]).css({
    
    
                                visibility: "hidden",
                            });
                        } else {
    
    
                            score.innerHTML = Number(score.innerHTML) - 2;
                            $(clickImg[0].children[0]).hide();
                            $(clickImg[1].children[0]).hide();
                        }
                        clickImg = [];
                        i = 0;
                    }, 400);
                }
            }
        };
    });
}

4. What is used to calculate A (10 points)

// TODO:请补充代码
const btn = document.getElementsByClassName("calc-button");
const formula = document.getElementById("formula");
const result = document.getElementById("result");

// 计算机表达式展示
let showText = "";
// 计算结果
let num = "";

[...btn].forEach((item) => {
    
    
    item.onclick = function () {
    
    
        switch (this.id) {
    
    
            // 点击 =
            case "equal":
                // eval() 函数会将传入的字符串当做 JavaScript 代码进行执行。
                num = eval(showText.replace("x", "*").replace("÷", "/"));
                result.value = num;
                return;
            // 点击 √
            case "sqrt":
                num = eval(showText.replace("x", "*").replace("÷", "/"));
                num = Math.sqrt(num);
                result.value = num;
                return;
            // 点击 AC
            case "reset":
                showText = "";
                num = "";
                formula.value = showText;
                result.value = num;
                return;
            default:
                showText += this.innerHTML;
                formula.value = showText;
                return;
        }
    };
});

5. New school gift giveaway (15 points)

The investigation is only on the implementation of the short-answer page. Everyone’s implementation is different, and the codes are also very different. I won’t put the code here.

6. Rights management (15 points)

$(function () {
    
    
    // 使用 ajax 获取 userList.json 数据并渲染到页面
    getData();

    // 为按钮添加事件
    $("#add").click(function () {
    
    
        // TODO:补充代码,实现功能

        // 获取选中的option
        let option = $("#leftSelect option:selected");

        // jQ方法:each() 遍历jQ获取的节点
        option.each((index, item) => {
    
    
            // 删除左侧对应的option
            $(`#leftSelect option[value=${
      
      item.value}]`).remove();
            // 向右侧添加option
            $("#rightSelect")[0].add(new Option(item.value, item.value));
        });

        changeAccess("管理员", option);
    });

    $("#addAll").click(function () {
    
    
        // TODO:补充代码,实现功能
        let option = $("#leftSelect option");
        option.each((index, item) => {
    
    
            $(`#leftSelect option[value=${
      
      item.value}]`).remove();
            $("#rightSelect")[0].add(new Option(item.value, item.value));
        });
        changeAccess("管理员", option);
    });

    $("#remove").click(function () {
    
    
        // TODO:补充代码,实现功能
        let option = $("#rightSelect option:selected");
        option.each((index, item) => {
    
    
            $(`#rightSelect option[value=${
      
      item.value}]`).remove();
            $("#leftSelect")[0].add(new Option(item.value, item.value));
        });
        changeAccess("普通用户", option);
    });
    $("#removeAll").click(function () {
    
    
        // TODO:补充代码,实现功能
        let option = $("#rightSelect option");
        option.each((index, item) => {
    
    
            $(`#rightSelect option[value=${
      
      item.value}]`).remove();
            $("#leftSelect")[0].add(new Option(item.value, item.value));
        });
        changeAccess("普通用户", option);
    });
});

/**
 * 修改权限
 * @param {Object} right 要修改的权限
 * @param {Object} changeList 要修改权限的用户列表
 */
function changeAccess(right, changeList) {
    
    
    // TODO:补充代码,实现功能
    changeList.each((index, item) => {
    
    
        // 将option.value与tr.name对应,找到对应的td并修改其内容
        // jQ方法::last 获取最后个元素
        $(`#userList tr[name=${
      
      item.value}] td:last`).html(right);
    });
}
// 异步获取数据
function getData() {
    
    
    // TODO:补充代码,实现功能
    $.ajax("./js/userList.json").then((res) => {
    
    
        res.forEach((item) => {
    
    
            // jQ方法:html() 设置html内容
            $("#userList tbody").html(
                $("#userList tbody").html() +
                    ` <tr name=${
      
      item.name}>
                         <td>${
      
      item.name}</td>
                         <td>${
      
      item.right ? "管理员" : "普通用户"}</td> 
                      </tr>`
            );
        });
    });
}

7. Let's have a meeting together (20 points)

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>一起会议吧</title>
    <link rel="stylesheet" type="text/css" href="./css/index.css" />
    <link rel="stylesheet" href="./css/iconfont/iconfont.css" />
</head>

<body>
    <div id="app">
        <!-- TODO:请在下面实现需求 -->
        <!-- 登录/注销窗口 -->
        <div class="login">
            <div class="left-tools">
                <a class="close-btn"></a>
                <a class="shrink-btn"></a>
            </div>
            <h3>{
    
    {
    
    isLogin?'注销':'登录'}}</h3>
            <p v-if="!isLogin">
                选择用户:<select id="selectUser" @change="changeOption($event)">
                    <option :value="item.id" v-for="item in list" :key="item.id">{
    
    {
    
    item.name}}</option>
                </select>
            </p>
            <p v-else>当前用户为:{
    
    {
    
    loginUser.name}}</p>

            <a class="login-btn" @click="btn">{
    
    {
    
    isLogin?'注销':'登录'}}</a>
        </div>

        <!-- 右侧显示用户列表窗口按钮 -->
        <button id="show" class="right-btn" v-if="!showUser&&isLogin" @click="showUser=true">
            <span class="iconfont icon-left-arrow"></span>
        </button>

        <!-- 用户列表窗口 -->
        <div class="user-dialog" v-if="isLogin&&showUser">
            <!-- 用户列表窗口上侧工具栏 -->
            <ul class="tools">
                <li class="tools-left">
                    <button :class="{'active':isButton<0}" @click="isButton=-1">
                        <span class="iconfont icon-close"></span>
                    </button>
                    <button :class="{'active':isButton=='0'}" @click="isButton=0">
                        <span class="iconfont icon-dialog"></span>
                    </button>
                    <button :class="{'active':isButton>0}" @click="isButton=1">
                        <span class="iconfont icon-list"></span>
                    </button>
                </li>
                <li class="tools-right">
                    <button class="show-list" @click="showUser=false">
                        <span class="iconfont icon-retract"></span>
                    </button>
                </li>
            </ul>

            <!-- 用户列表 -->
            <ul class="say-list">
                <li>
                    <span class="iconfont icon-microphone"></span>
                </li>
                <li class="line"></li>
                <li>正在讲话:{
    
    {
    
    list.find(item=>item.isHost).name}}</li>
            </ul>
            <ul class="user-list">
                <li v-show="isButton>=0">
                    <img class="header" :src="loginUser.imgPath" />
                    <div class="user-name">
                        <span class="iconfont icon-user header-icon" v-if="loginUser.isHost"></span>
                        <span class="iconfont icon-microphone"></span> {
    
    {
    
    loginUser.name}}
                    </div>
                </li>
                <li v-for="item in list" :key="item.id" v-if="item.id!==loginUser.id" v-show="isButton>0">
                    <img class="header" :src="item.imgPath" />
                    <div class="user-name">
                        <span class="iconfont icon-user header-icon" v-if="item.isHost"></span>
                        <span class="iconfont icon-microphone"></span> {
    
    {
    
    item.name}}
                    </div>
                </li>

            </ul>
        </div>
    </div>
    <script type="text/javascript" src="./js/vue.js"></script>
    <script type="text/javascript" src="./js/axios.min.js"></script>
    <script type="text/javascript">
        // TODO:请在下面实现需求
        new Vue({
    
    
            el: "#app",
            data: {
    
    
                // 用户列表
                list: [],
                // 选择用户id
                value: '1',
                // 是否登录
                isLogin: false,
                // 是否显示用户参会窗口
                showUser: true,
                // 登录的用户信息
                loginUser: {
    
    },
                // 用户列表显示效果切换的状态
                isButton: 0
            },
            created() {
    
    
                axios.get('./js/userList.json').then(res => {
    
    
                    this.list = res.data
                })
            },
            methods: {
    
    
                btn() {
    
    
                    this.isLogin = !this.isLogin
                    if (this.isLogin) {
    
    
                        this.loginUser = this.list.find(item => item.id == this.value)
                    } else {
    
    
                        this.loginUser = {
    
    }
                        this.value = '1'
                        this.isButton = 0
                        this.showUser = true
                    }
                },
                // 选择下拉框用户时
                changeOption(e) {
    
    
                    this.value = e.target.value
                }
            }

        });
    </script>
</body>

</html>

8. Weather Trend A (20 points)

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>天气趋势</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <link rel="stylesheet" type="text/css" href="css/style.css" />
    <script src="./js/axios.js"></script>
    <script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="js/echarts.min.js" type="text/javascript" charset="utf-8"></script>
</head>

<body>
    <div id="app">
        <div class="top-bar">2022Y 城全年温度统计图</div>
        <!-- 主体 -->
        <div class="container">
            <!-- 月份 -->
            <div class="month">
                <ul>
                    <!-- TODO:待补充代码 在下面的 li 标签中完成 12个月份 (即 monthList) 的渲染  -->
                    <!-- 选择月份的英文名称等于数据中的key,代表这条数据选中 -->
                    <li v-for="(item,key,index) in monthList" :class="[monthName===key?'active':'']" @click="changeMonth(key,index)">
                        {
    
    {
    
    item}}</li>
                </ul>
            </div>
            <div class="chart">
                <!-- TODO:待补充代码  -->
                <!-- currentMonth  未来七天和本月 tab 切换,只有当前月才显示 -->
                <!-- 选择月份的序号(对应月份-1)等于当前月份的标志(当前月份-1)时显示 -->
                <div id="currentMonth" v-if="monthNumber===nowMonth">
                    <div class="title">
                        <h3>{
    
    {
    
    typeTitle}}</h3>
                        <div class="type" @click="clickType($event)">
                            <span id="seven" :class="{'active':!type}">未来7</span>
                            <span id="current" :class="{'active':type}">本月</span>
                        </div>
                    </div>
                </div>
                <div id="chart"></div>
            </div>
        </div>
    </div>
</body>

</html>
<script>
    // TODO:待补充代码
    var vm = new Vue({
    
    
        el: "#app",
        data: {
    
    
            chart: null, // 图表
            chartOptions: null, // 图表配置项
            typeTitle: "本月天气",
            monthList: {
    
    
                January: "1月",
                February: "2月",
                March: "3月",
                April: "4月",
                May: "5月",
                June: "6月",
                July: "7月",
                August: "8月",
                September: "9月",
                October: "10月",
                November: "11月",
                December: "12月",
            },
            // 请求到的全部数据
            data: [],
            // 选择月份的英文名称
            monthName: 'January',
            // 选择月份的序号(对应月份-1)
            monthNumber: 0,
            // 当前月份的标志(当前月份-1)
            nowMonth: new Date().getMonth(),
            // x轴,y轴数据
            yData: [],
            xData: [],
            // 未来7天和本月数据的状态
            type: 1
        },

        mounted: async function() {
    
    
            const res = await axios.get('./js/weather.json');
            this.data = res.data;
            // 初始化x轴和y轴数据
            this.yData = res.data[0]['January'];
            // 根据y轴温度数据条数的多少判断x轴有多少天
            this.xData = [...this.yData.map((e, i) => i + 1)];
            // 初始化 echarts
            this.$nextTick(() => {
    
    
                this.initChart();
            });
        },
        methods: {
    
    
            initChart() {
    
    
                // 初始化图表
                this.chart = echarts.init(document.getElementById("chart"));
                // 配置项
                this.chartOptions = {
    
    
                    grid: {
    
    
                        top: 35,
                        bottom: 5,
                        left: 10,
                        right: 10,
                        containLabel: true,
                    },
                    tooltip: {
    
    
                        trigger: "axis",
                        axisPointer: {
    
    
                            lineStyle: {
    
    
                                color: {
    
    
                                    type: "linear",
                                    x: 0,
                                    y: 0,
                                    x2: 0,
                                    y2: 1,
                                    colorStops: [{
    
    
                                        offset: 0,
                                        color: "rgba(255,255,255,0)",
                                    }, {
    
    
                                        offset: 0.5,
                                        color: "rgba(255,255,255,1)",
                                    }, {
    
    
                                        offset: 1,
                                        color: "rgba(255,255,255,0)",
                                    }, ],
                                    global: false,
                                },
                            },
                        },
                    },
                    xAxis: [{
    
    
                        type: "category",
                        boundaryGap: false,
                        axisLabel: {
    
    
                            formatter: "{value}",
                            fontSize: 12,
                            margin: 20,
                            textStyle: {
    
    
                                color: "#bfbfbf",
                            },
                        },
                        axisLine: {
    
    
                            lineStyle: {
    
    
                                color: "#e9e9e9",
                            },
                        },
                        splitLine: {
    
    
                            show: true,
                            lineStyle: {
    
    
                                color: "#f7f7f7",
                            },
                        },
                        axisTick: {
    
    
                            show: false,
                        },
                        // x 轴显示的数据,日期
                        data: this.xData,
                    }, ],
                    yAxis: [{
    
    
                        boundaryGap: false,
                        type: "value",
                        axisLabel: {
    
    
                            textStyle: {
    
    
                                color: "#bfbfbf",
                            },
                            formatter: `{value}\u2103`,
                        },
                        nameTextStyle: {
    
    
                            color: "#fff",
                            fontSize: 12,
                            lineHeight: 40,
                        },
                        splitLine: {
    
    
                            lineStyle: {
    
    
                                color: "#f7f7f7",
                            },
                        },
                        axisLine: {
    
    
                            show: true,
                            lineStyle: {
    
    
                                color: "#e9e9e9",
                            },
                        },
                        axisTick: {
    
    
                            show: false,
                        },
                    }, ],
                    series: [{
    
    
                        name: "天气",
                        type: "line",
                        smooth: false,
                        showSymbol: false,
                        symbolSize: 0,
                        zlevel: 3,
                        itemStyle: {
    
    
                            color: "#ff6600",
                            borderColor: "#a3c8d8",
                        },
                        lineStyle: {
    
    
                            normal: {
    
    
                                width: 3,
                                color: "#ff6600",
                            },
                        },
                        areaStyle: {
    
    
                            normal: {
    
    
                                color: new echarts.graphic.LinearGradient(
                                    0,
                                    0,
                                    0,
                                    1, [{
    
    
                                        offset: 0,
                                        color: "#ff6600",
                                    }, {
    
    
                                        offset: 0.8,
                                        color: "#ff9900",
                                    }, ],
                                    false
                                ),
                            },
                        },
                        //  Y 轴显示的数据,即温度数据
                        data: this.yData,
                    }, ],
                };

                // 调用此方法设置 echarts 数据
                this.chart.setOption(this.chartOptions);
            },
            // 切换月份
            changeMonth(month, index) {
    
    
                this.monthName = month;
                this.monthNumber = index;

                this.yData = this.data[index][month];
                this.xData = [...this.yData.map((e, i) => i + 1)];

                // 如果切换到了当前月份,将type状态重置以下
                if (index === this.nowMonth) {
    
    
                    this.type = 1
                }
                this.initChart()
            },
            // 切换未来7天和本月
            clickType(e) {
    
    
                switch (e.target.id) {
    
    
                    case "seven":
                        this.type = 0;
                        // 解构赋值更新x,y坐标轴的数据
                        [this.xData, this.yData] = this.getSevenData();
                        break;
                    case "current":
                        this.type = 1
                        this.yData = this.data[this.monthNumber][this.monthName]
                        this.xData = [...this.yData.map((e, i) => i + 1)]
                        break;
                }
                this.initChart();
            },
            // 获取未来七天数据
            getSevenData() {
    
    
                let newXdata = [],
                    newYdata = [];
                // 利用循环一天一天的获取
                for (let i = 0; i < 7; i++) {
    
    
                    // 当前时间
                    let now = new Date();
                    // now.getTime()为当前时间戳 time为需要获取的那天的时间戳
                    let time = now.getTime() + 1000 * 60 * 60 * 24 * i;
                    // 用setTime转换,将now转换为需要获取的那天的时间
                    // now.setTime(time)既是设置now的日期为:从1970.1.1开始走过time毫秒后的日期
                    now.setTime(time);

                    newXdata.push(`${
      
      now.getMonth() + 1}/${
      
      now.getDate()}`)

                    if (this.monthNumber === now.getMonth()) {
    
    
                        // 如果当前选择的月份与获取那天的时间所处月份一样,则直接取当前y轴里的数据
                        newYdata.push(this.yData[now.getDate() - 1])
                    } else {
    
    
                        // 如果当前选择的月份与获取那天的时间所处月份不同,说明进入到了下一月份,取下一月份的数据
                        let nextMonth = this.data[now.getMonth()];
                        // 因为不确定月份数据里的key是啥,不能直接取,所以采用for in遍历对象间接获取数据
                        for (const key in nextMonth) {
    
    
                            newYdata.push(nextMonth[key][now.getDate() - 1])
                        }
                    }
                }
                return [newXdata, newYdata]


            }
        },
    });
</script>

9. JSON generator (25 points)

I really can't do this. . .
Ask the big guys for answers online

10. Mall management system (25 points)

// menuList 仅为示例数据,非实际使用数据,实际使用数据层级不确定(可能是四级五级六级等),数据结构与 menuList 一致
// 1. `parentId` 如果为 `-1`,则表示此条数据为顶级数据。
// 2. `parentId` 为该条数据的父级数据的 `id`。

let menuList = [
    {
    
     parentId: -1, name: "添加管理员", id: 10, auth: "admin" },
    {
    
     parentId: 10, name: "管理员权限分配", id: 11, auth: "admin-auth" },
    {
    
     parentId: -1, name: "商品管理", id: 1, auth: "product" },
    // { parentId: 6, name: "赤门网络暗杀速度还等哈说", id: 12, auth: "product" },
    {
    
     parentId: 1, name: "商品列表", id: 4, auth: "productList" },
    {
    
     parentId: 4, name: "商品分类", id: 5, auth: "category" },
    {
    
     parentId: 5, name: "添加分类", id: 8, auth: "addClassification" },
    {
    
     parentId: 4, name: "商品上架", id: 6, auth: "product" },
    {
    
     parentId: -1, name: "评论管理", id: 2, auth: "comments" },
    {
    
     parentId: -1, name: "个人中心", id: 3, auth: "profile" },
];

/**
 * @param {*} menuList 传入的数据
 * @return {*} menus 转化后的树形结构数据,auths 转化后的权限列表数组
 */

const getMenuListAndAuth = (menuList) => {
    
    
    // TODO:待补充代码
    let menus = [],
        auths = [],
        // emenus存放那些还未找到上级(未被push的项)
        emenus = [],
        // 项是否被落下(是否未被push)
        isDiscard = true;

    // 创建一个能够递归查找push的函数
    function addChildren(fat, chil) {
    
    
        fat.forEach((fatItem) => {
    
    
            if (fatItem.id === chil.parentId) {
    
    
                fatItem.children.push(chil);
                // 只要项被push了,说明它没有被落下,立即修改isDiscard
                isDiscard = false;
                return;
            } else {
    
    
                // 递归
                addChildren(fatItem.children, chil);
            }
        });
    }

    // 遍历原数据
    menuList.forEach((item) => {
    
    
        // 每一次遍历数据时都提前默认isDiscard为true,因为此时数据还未被push
        isDiscard = true;
        item.children = [];

        auths.push(item.auth);

        if (item.parentId === -1) {
    
    
            menus.push(item);
            isDiscard = false;
        } else {
    
    
            addChildren(menus, item);
            // 一次遍历结束了,如果isDiscard还为true,即还未被push
            // 说明这一项的父级还没有出现,为了防止这一项丢失,将它暂存到emenus中
            if (isDiscard) {
    
    
                emenus.push(item);
            }
        }
    });

    // 转换的过程结束了,如果emenus不为空,说明有项被丢弃落下了
    // 项被落下的原因是:它的父级比它出现的晚,在顺序遍历到它时,因前面没有它的父级,导致它无法被接收
    if (emenus.length !== 0) {
    
    
        // 这时其它项已经全部加入menus,此时再次将emenus中被落下的项向menus中添加肯定能加上
        emenus.forEach((item) => {
    
    
            addChildren(menus, item);
        });
    }

    return {
    
     menus, auths }; // menus 转化后的树形结构数据,auths 转化后的权限列表数组
};

// 请勿删除和修改以下代码
try {
    
    
    module.exports = {
    
     getMenuListAndAuth };
} catch (e) {
    
    }

Summary

If the previous provincial competition was a big flood, this time the national competition is a real dry field, without a little water (it felt like this when I took the test). To sort, I immediately thought of the built-in sorting method on the array prototype, but the irony is that I forgot which one it was, logprinted it Array.prototype, and then I tried whichever one looked like it, but finally saw that time had passed It's been half an hour, I'm in a hurry, and I have to use the stupid but simple method of bubble sorting

In this way, I apiwasted too much time on thinking, and the reason is that my foundation is not strong enough.

Because the provincial competition was too much, before the exam, I always felt that the national competition might be the same. During the exam, I took my time and took my time. When I encountered a good way to achieve it, I couldn’t think of it for a while api. I didn't skip it, I just kept thinking about it, but the time just dragged on and passed away. When I really realized that there was not enough time and I couldn't procrastinate any more, it was already too late.

Hey, now I went back and did the question again, and found that the time I spent on writing the last question was less than half of the time wasted on the first question during the exam. Because I didn’t have enough time at the end of the exam, I didn’t read the last question at all. Really Irony.

Thanks to this Blue Bridge Cup experience, I really realized my own shortcomings and the direction of my efforts.

I would like to use this article to record my experience of failure

Guess you like

Origin blog.csdn.net/m0_51969330/article/details/125360660