首页 > 其他分享 >22207334-章莲祥第一次博客

22207334-章莲祥第一次博客

时间:2024-10-26 18:09:05浏览次数:1  
标签:questionNumber 题目 String question 博客 章莲祥 答案 answer 22207334

一、前言

对于这三次作业的知识点来讲我认为是相当密集的,无论是第一次作业中有无参构造方法、类和对象的使用和字符串的接收处理和输出,又或是往后的第二三次作业,都让我在思考中学到了很多。就题量来讲的话,基础类的题较多,难题虽少但是确实够难,

题量上的设置在我看来还是合理的。难度的话对我个人来说还是较大,对java中面向对象的思想还不是很能熟练运用,比如在一次大作业的时候对类的设置就没有设好,导致后续花了很长时间来精简代码。总体来说这三次作业的质量还是蛮高,我也从中学

到了很多。

二、第一次作业

 

在第一题设计一个风扇Fan类的过程中,了解到了有参构造和无参构造的区别,无参构造默认参数相较于有参构造还是太死板,不过可以用来快速判断对象是否创建。

 

 

第二题类和对象的使用,学习到了toString()方法和printInfo()方法,从而可以快速的将对象的属性信息按照指定形式输出出来。

 第三题成绩计算-1-类、数组的基本运用,一开始对输入样例里的

22201311 张琳 80 80 80
22201312 黄昊 66 82 81
22201313 李少辰 77 76 80
22201314 袁婷 62 79 90
22201315 朱哲一 74 98 94

一大串学号、姓名还有各科成绩不知道怎么去接收处理,想去用数组但无法把不同人的各科成绩分开来,后面网上查了一下了解到了字符串的split分割方法,于是便用这个方法来分开数据

Student[] students = new Student[5];
for (int i = 0; i < 5; i++) {
String[] input = scanner.nextLine().split(" ");
students[i] = new Student(input[0], input[1], Integer.parseInt(input[2]), Integer.parseInt(input[3]), Integer.parseInt(input[4]));
}

首先创建students 数组存储五个学生对象,为后面接收数据构造Student对象做准备,

String[] input = scanner.nextLine().split(" ");这一句首先是一行一行接收,然后又以空格切割,完美的提取出了每个学生的各项数据,让后面创建学生对象都不需做什么处理直接就new。

 

第四题成绩计算-2-关联类是在第三题的基础上添加两个方法,一个计算总成绩的方法和一个计算总分的方法,这题思路上没问题,但是一开始没看到各科分数计算规则定义

错了方法导致了几次错误提交;这题有一个小难点在于怎么把字符串转为浮点数而且还要实现四舍五入:

 

String formattedOutput = String.format("%s %s %d %.2f %.2f %.2f\n", id, name, all, avr_sim, avr_end, avr);

在网上搜索了解到了String.format方法来转化字符串

 

 

import java.math.BigDecimal;
import java.math.RoundingMode;

导入了数学的两个库,使用库里的方法比自己实现要省了不少功夫,这也是java的优势的体现吧

BigDecimal bd = new BigDecimal(re);
bd = bd.setScale(2, RoundingMode.HALF_UP); // 设置小数点后两位并四舍五入

 

  第五题 答题判题程序-1是第一次大作业,一开始看到这题确实被它这么多测试点和输入样例给唬住了,在完成过程遇到了问题: 1、首先是类的设计,一开始只用两个类答案类和问题类, 这样导致答案类里面东西太多而且冗余,后面新增了试卷类(用于封装整套题目的信息)后,答案类就可以不用对题目的格式读取负责了,优化了代码结构。 2、对于输入中的#N、#Q、#A怎么去读取,读取之后怎么去接收后面的数据,这个问题属实花了不少功夫
Pattern pattern = Pattern.compile("#(.*?):");
        Matcher matcher = pattern.matcher(responseLine);

        while (matcher.find()) {
            // 提取响应并追加到responseSheet
            String response = matcher.group(1).trim();
            // 假设有一个方法appendResponse来处理响应
            responseSheet.appendResponse(response);
        }
一开始使用正则表达式来接收,但是发现这样分割出来的答案会时多一个符号时少一个答案,调试了很久没找出问题后面还是采取了分割的方法

String[] responseSegments = responseLine.split("#");
for (int j = 1; j < responseSegments.length; j++) {
String response = responseSegments[j].split(":")[1].trim();
responseSheet.appendResponse(response);

先对#进行分割,分割出不同的答卷,后面对:分割取其冒号后部分也就是答案存入答卷数组里  

三、第二次作业

第一题 手机按价格排序、查找的题目中使用到了Collections类的sort方法,这又是一个对链表对象快速排序的高效方法:

Collections.sort(phones);

排序之后再遍历一遍链表

public int compareTo(MobilePhone other) { return Integer.compare(this.price, other.price); }

 

定义compareTo方法来快速比较价格便于于第四部手机比较价格并输出结果   第四题 大作业2 这次大作业难度比第一次大作业提升了很多,首先是三种信息输入的顺序被打乱了,这意味着在输入接收部分的代码需要改动。然后是新增的试卷信息以及题目分值,这将增加一个“#T"的判断以及判题之后对分值的累积。同时也增加了一个试卷未满分的判断,这让我一开始往 代码中添加了分值类,然后这是个错误,因为它涉及的范围很广。以下是我初始的类图:    

 

在第一次大作业代码问题类、答卷类、答案类基础上添加一个分值类,它的作用是判分生成记录答案等。但是这个类的功能实现起来很困难,因为它包含了三个类,需要调用不同的方法来实现判分。

不过一开始的版本中对输入的处理做的比较好,

 if (line.startsWith("#N:")) {

                // Process question input

                String[] parts = line.split(" ", 3);

                if (parts.length < 3) continue;

                int id = Integer.parseInt(parts[0].substring(3));

                String content = parts[1].substring(3);

                String answer = parts[2].substring(3);

                grader.addQuestion(new Question(id, content, answer));

先对#后的符号判断来判断输入给哪个类,然后按空格分三部分,再分别处理。这样可以高效的处理输入的数据。

使用Grader类实现功能时第一个输入样例总过不去,于是后面完善了一下processAnswers()答案处理判分函数。

 

for (Map.Entry<Integer, Integer> entry : testPaper.questionsAndScores.entrySet()) {

 

                Question question = questions.get(entry.getKey());

 

                String answer = getAnswerByIndex(answerSheet.answers, entry.getKey());

 

                boolean isCorrect = answer != null && answer.equals(question.answer);

 

                int score = isCorrect ? entry.getValue() : 0;

 

                totalScore += score;

 

 

 

 ... }

 

在for循环里先逐个提取出问题与答案,然后使用equals方法判断正误,返回一个boolean结果用于打印输出,同时true就加入总分里。

 

 String outputAnswer = answer != null && answer.startsWith("#A:") ? answer.substring(3) : answer;

 

                // Output the question content and the answer

 

                System.out.println(question.content + "~" + outputAnswer + "~" + (isCorrect ? "true" : "false"));

之前读取答案过程中总是把" #A"给读取进来,总而导致每次判题的时候对的也能判成错的。声明一个outputAnswer来接收过滤掉" #A"的答案再比较。

在进行了诸多改进之后,到了样例5乱序输入的情况下我的接收逻辑又出现错误了,参照检测点11 12做出了改进:

打印警报信息:在处理测试卷的最大分数时,增加了输出具体测试卷 ID 的警告信息,以便于识别是哪个测试卷的问题。

System.out.println("alert: full score of test paper" + testPaper.id + " is not 100 points");

答案输出处理:在输出答案时,检查答案是否为 null,并提供相应的输出,防止程序尝试打印 null 值。

if (answer == null){
  System.out.println(question.content + "~" + "answer is null" + "~false");
} 

else { System.out.println(question.content + "~" + outputAnswer + "~" + (isCorrect ? "true" : "false")); }

 

 

  添加了警告以后,通过了检测点11、12,但是仍然通不过样例4、5,这时我Grader类里的代码已经相当的冗余,在多次修改无用之后,我决定重新设计类图

新的类设计中新增了验证器类Validator和记分器类ScoreCalculator ,同时不再由Main来调用这些类而是新建了一个考试系统类ExanSystem来调用这些方法,这样Main类只需处理用户输入已经调用系统了,

代码逻辑更加清晰了。

验证器类Validator中包含两个验证方法validateFullScore和validateTestPaperExistence 分别用来验证试卷是否满分和试卷是否存在(可能被删除)。

记分器类ScoreCalculator包含一个计分方法calculateAndDisplayScores,这个方法能输出每道题的得分以及总分,它的核心代码如下:

 System.out.println(question.content + "~" + (answer != null ? answer : "answer is null")

                               + "~" + isCorrect);

            scoresPerQuestion.add(score);

            questionIndex++;

考试系统类ExanSystem需要调用并且存储各类链表对象:

 private Map<Integer, Question> questions = new HashMap<>();

    private Map<Integer, TestPaper> testPapers = new HashMap<>();

    private List<AnswerSheet> answerSheets = new ArrayList<>();

    private ScoreCalculator scoreCalculator = new ScoreCalculator();

    private Validator validator = new Validator();

类开头就创建存储各个不同对象的私有链表。

核心方法processAllAnswerSheets:

 for (AnswerSheet answerSheet : answerSheets) {

            TestPaper testPaper = testPapers.get(answerSheet.testPaperId);

 

            if (!validator.validateTestPaperExistence(testPaper, answerSheet.testPaperId)) {

                continue;

            }

 

            int maxPossibleScore = testPaper.calculateTotalScore();

            validator.validateFullScore(maxPossibleScore, testPaper.id);

  1. 外层的 for 循环遍历 answerSheets 列表,这个列表包含了所有的 AnswerSheet 对象,每个对象代表一个学生的答卷。
  2. 对于每个 AnswerSheet 对象,通过 answerSheet.testPaperId 来获取对应的 TestPaper 对象。testPapers 是一个映射,它根据试卷的 ID 存储对应的 TestPaper 对象。
  3. 接下来,使用 validator 对象的 validateTestPaperExistence 方法来检查是否存在对应的 TestPaper 对象。如果 TestPaper 对象不存在(即 testPaper 为 null),则打印一条消息并使用 continue 语句跳过当前循环,继续处理下一个 AnswerSheet 对象。
  4. 如果 TestPaper 对象存在,就调用它的 calculateTotalScore 方法来计算该试卷的总分。
  5. 然后,使用 validator 对象的 validateFullScore 方法来检查试卷的总分是否为100分。如果总分不是100分,打印一条警告消息。

  这段代码的目的是确保每个学生的答卷都与一个有效的试卷相关联,并且该试卷的总分符合预期(在这个例子中是100分)。如果有任何不一致,它会打印相应的消息并继续处理下一个学生的答卷。

 

四、第三次大作业

第三次大作业在第二次作业的基础上多了很多检测点,同时第三次大作业中开始对含错误格式输入、有效删除以及无效题目引用信息、含错误格式输入、有效删除、无效题目引用信息以及答案没有输入、

输入的优先级、无效的试卷符号引用、信息输入顺序、答卷顺序输出这几个方面设置了输入输出样例。在第二次大作业我的类设计中这些都是不曾考虑进来的,因此在第二次大作业基础上写这次作业让我

很痛苦,于是我开始重新设计类结构。初始类图如下:

 

初始类图设计相当简单,考虑必须的三个类以外添加了Student类和TestSystem类,其中的TestSystem类中需要实现创建删除题目、检查题目顺序、判分输出等功能,

 deleteQuestion方法一开始使用的是标记被删除的题号,将其存放于questions数组中

if (questions.containsKey(questionNumber)) {
// 从题目集合中删除
questions.remove(questionNumber);
System.out.println("Question " + questionNumber + " has been deleted.");

TestSystem类中比较核心的方法handleAnswerSheet用来处理学生提交的答题卡。通过检查试卷和学生是否存在,解析每道题的答案并记录。调用 evaluateAnswerSheet 方法对答题卡进行判分:

for (String ans : answers) {

            String[] parts = ans.split("-");

            if (parts.length != 2) {

                System.out.println("wrong format:" + ans);

                continue;

            }

            try {

                int questionOrder = Integer.parseInt(parts[0].substring(3)); // 提取顺序号

                String answer = parts[1].trim();

                answerSheet.addAnswer(questionOrder, answer);

            } catch (Exception e) {

                System.out.println("wrong format:" + ans);

            }

该代码实现的逻辑:

 

    1. 遍历学生提交的答案 (answers):

      • answers 是一个 String[] 数组,每个元素是一个题目的答案,格式为 "顺序号-答案",例如 "Q01-A"
    2. 解析答案格式:

      • String[] parts = ans.split("-");
        这行代码通过 "-" 分割字符串,将每个题目的信息分成两部分:题目的顺序号和学生的答案。
        • parts[0]:题目顺序号(如 "Q01")。
        • parts[1]:学生给出的答案(如 "A")。
    3. 检查格式是否正确:

      • if (parts.length != 2):检查分割后的数组是否有两个部分,如果不等于2,说明格式有误。
      • 如果格式不正确,则输出 "wrong format" 并跳过当前答案的处理。
    4. 提取题目顺序号:

      • int questionOrder = Integer.parseInt(parts[0].substring(3));
        这里通过 substring(3) 提取题目的顺序号(去掉前缀,如 "Q01" 中的 "Q",保留数字 "01")。然后,将其转化为整数。
        • 假设题号格式为 "Q01"substring(3) 提取出的是 "01",然后转化为整数 1
    5. 提取并处理学生的答案:

      • String answer = parts[1].trim();
        提取分割后的答案部分,并使用 trim() 去除首尾的空格,防止意外的空白字符。
    6. 将题目顺序号和答案存入答题卡:

      • answerSheet.addAnswer(questionOrder, answer);
        将提取到的题目顺序号和答案添加到 AnswerSheet 中。
    7. 错误处理:

      • 如果在提取顺序号或答案过程中出现异常(例如,题号格式不对导致无法转换为整数),会捕获异常,并输出 "wrong format" 错误信息

 

然而实际运行上这段代码并未通过格式检查点,这个问题出在异常处理以及格式判断的缺乏。

TestSystem类中另一核心的方法evaluateAnswerSheet用来根据试卷的题目顺序和分值判分。跳过已删除题目或不存在的题目,空答案会给出提示。判分完成后,输出学生的总分情况。

遍历题目判分代码:

  for (Map.Entry<Integer, Integer> entry : testPaper.questionsWithPoints.entrySet()) {

        int questionNumber = entry.getKey();

        int points = entry.getValue();

        // 判断题目是否被删除

        if (deletedQuestions.contains(questionNumber)) {

            System.out.println("the question " + questionNumber + " invalid~0");

            continue;  // 跳过后续逻辑

        }

 

        // 判断题目是否不存在

        if (!questions.containsKey(questionNumber)) {

            System.out.println("non-existent question~0");

            continue;  // 跳过后续逻辑

        }

        // 获取学生的答案

        String studentAnswer = answerSheet.answers.getOrDefault(questionNumber, "");

        Question question = questions.get(questionNumber);

        // 优先判断答案是否为空

        if (studentAnswer.isEmpty()) {

            System.out.println(question.content + "~answer is null");

        } else {

            boolean isCorrect = studentAnswer.equals(question.correctAnswer);

            System.out.println(question.content + "~" + studentAnswer + "~" + isCorrect);

            if (isCorrect) {

                totalScore += points;  // 只有在答案正确时才加分

            }

        }

    }

该代码实现逻辑:

 

  1. 遍历试卷中的每个题目:

    • 通过 testPaper.questionsWithPoints.entrySet() 遍历试卷中的每一道题目及其对应的分值。
    • entry.getKey():获取题目的编号 (questionNumber)。
    • entry.getValue():获取题目的分值 (points)。
  2. 检查题目是否已删除:

    • if (deletedQuestions.contains(questionNumber)):判断当前题目是否在 deletedQuestions 集合中,即是否已被删除。
    • 如果已删除,则输出 "the question {questionNumber} invalid~0",并跳过该题的评估。
  3. 检查题目是否不存在:

    • if (!questions.containsKey(questionNumber)):判断当前题目是否存在于 questions 集合中。如果不存在,表示题目无效。
    • 输出 "non-existent question~0",并跳过该题的评估。
  4. 获取学生的答案:

    • String studentAnswer = answerSheet.answers.getOrDefault(questionNumber, "");
      从 answerSheet 中获取学生针对当前题目的**。如果学生没有答该题,默认返回空字符串。
  5. 判断学生答案是否为空:

    • if (studentAnswer.isEmpty()):检查学生是否未对该题作答。
    • 如果答案为空,输出题目的内容以及 "answer is null" 以提示学生未作答。
  6. 判断答案是否正确:

    • boolean isCorrect = studentAnswer.equals(question.correctAnswer);
      比较学生的答案和题目的正确答案,判断是否匹配。
    • 输出当前题目的内容、学生的答案以及是否正确的布尔值。
    • 正确答案加分:如果答案正确,则累加对应题目的分值到总分 totalScore
然而实际测试过程中,该代码存在很多问题:
  1. 对已删除题目处理的改进:

    • 目前直接在评估时跳过已删除题目,但实际上删除题目时可以在 deletedQuestions 中直接更新或移除题目的相关数据,避免在评估时每次都检查。
  2. 对不存在题目的处理逻辑:

    • 如果某个题目不存在但依然出现在试卷中,可能是数据管理上的问题。在 addTestPaper 时,可以对题目编号的有效性进行验证,而不是在评估时发现问题。
  3. 答案为空的处理:

    • 如果学生未作答,可以选择在最终的得分报告中专门列出未答题目,而不仅仅在评估过程中的输出中显示。
  4. 答案判定的改进:

    • 目前的答案判定是精确匹配 equals,如果允许部分匹配或对大小写不敏感,可以改用 equalsIgnoreCase 或自定义匹配逻辑。
  5. 输出的信息量:

    • 每道题目的评估结果都逐个输出,可能在处理大规模答卷时显得繁琐。可以考虑将详细的题目评估记录到日志文件中,而只在控制台输出总成绩或错误信息
在这个基础上我修正了删除题目逻辑:

 // 判断题目是否被删除

        if (deletedQuestions.contains(questionNumber)) {

            System.out.println("the question " + questionNumber + " invalid~0");

            continue;  // 跳过后续逻辑

        }

 

        // 判断题目是否不存在

        if (!questions.containsKey(questionNumber)) {

            System.out.println("non-existent question~0");

            continue;  // 跳过后续逻辑

        }

这个逻辑将被删除题目的题号包含在deletedQuestions数组中,并且在判分的时候遍历数组,如果已被删除则 continue;  // 跳过后续逻辑并输出"the question " + questionNumber + " invalid~0",这使我通过了检测点9和11对无效题目的处理。

大作业3我完成的并不理想,一来是类的设计太简单,二来是对于题目中提到的对含错误格式输入、有效删除以及无效题目引用信息、含错误格式输入、有效删除、无效题目引用信息以及答案没有输入、

 

输入的优先级、无效的试卷符号引用、信息输入顺序、答卷顺序输出这几个方面都没有进行处理,这是我个人面向对象思想还没有理解的体现,在后面的学习中我得认真去攻克这些方面了。

五、总结

在过去的三次作业中,我经历了从基础到高级的Java编程实践,这些作业不仅加强了我的编程技能,也加深了我对面向对象编程(OOP)的理解。以下是我的主要收获和反思:

  1. 基础建设与概念理解:

    • 我学习了如何使用构造方法来初始化对象状态,体会到了无参构造方法在对象创建中的便捷性及其局限性。
    • 通过实际操作,我掌握了类和对象的使用,如何利用toString()printInfo()等方法来输出对象信息,这让我对OOP有了更直观的认识。
  2. 数据处理与类设计:

    • 我通过处理字符串输入和数组操作,学会了如何将复杂的数据结构分解为可管理的部分,这对我的编程逻辑有很大帮助。
    • 我意识到了类设计的重要性,一个良好的类设计可以大大简化代码的复杂性,提高代码的可维护性。
  3. 面向对象的深入应用:

    • 在处理更复杂的编程任务时,我学会了如何使用类来封装数据和行为,如何通过方法来实现具体的功能。
    • 我认识到了代码重构的必要性,随着对问题理解的深入,我不断调整和优化我的类结构,以适应新的需求和挑战。
  4. 错误处理与有效性验证:

    • 我学会了如何对输入数据进行有效性验证,以及如何处理错误和异常情况,这对于编写健壮的程序至关重要。
    • 我意识到了在设计类和方法时需要考虑的边界情况和潜在的错误,这让我的代码更加健壮和可靠。
  5. 代码优化与重构:

    • 我通过不断的实践,学会了如何识别和重构冗余代码,如何通过提取公共代码来简化程序结构。
    • 我认识到了代码优化的重要性,不仅仅是为了提高性能,更是为了提高代码的可读性和可维护性。
  6. 面向对象思想的深入:

    • 我深刻体会到了面向对象编程的核心思想,如封装、继承和多态,这些概念在我的编程实践中逐渐变得清晰。
    • 我意识到了面向对象不仅仅是一种编程范式,更是一种思考问题和解决问题的方式。

通过这三次作业,我不仅提升了自己的编程技能,也学会了如何更好地组织和管理复杂的代码。我认识到了自己在面向对象编程方面的不足,并决心在未来的学习中加以改进。我相信,随着实践经验的积累,我将能够更加自信地应用这些概念,并在软件工程领域取得更大的进步。

 

 

标签:questionNumber,题目,String,question,博客,章莲祥,答案,answer,22207334
From: https://www.cnblogs.com/zlx0912/p/18504307

相关文章

  • 算法博客链接
    算法好博客:\(\boxed{\text{莫队好博客}}\)\(\boxed{\text{生成函数好博客}}\)\(\boxed{\text{exkmp好博客}}\)\(\boxed{\text{明日方舟防沉迷破解}}\)套路做法关于对称图像的路径,珂以考虑对称回来。连通块的积考虑拆成组合意义:连通块内分别选一个点的方案数。对于一堆点的......
  • 基于ssm框架的博客系统【附源码】
    基于ssm框架的博客系统(源码+L文+说明文档)   目录4系统设计  4.1系统概述  5系统的实现5.1功能模块的实现5.2博客信息管理  5.3博客类型管理  5.4公告信息管理  4系统设计  4.1系统概述  本文通过B/S结构(Browser/Server,浏览器/服务器结......
  • 查看博客园的总阅读量
    打开博客园后台Link然后按F12进入控制台,接下来输入下面的代码就好啦/**在最后一行修改博客地址用户名就好啦*/functioncountBlogReadings(CnblogsName){console.log("正在统计"+CnblogsName+"的博客的总阅读量...");//任务线程内部的全局变量数组,用于保......
  • Servlet实现博客系统
    博客系统一。博客系统的基本情况:1.四个页面:(1)博客列表页,显示列表页上有哪些博客(2)博客详情页,点击某个博客可以观看对应的详情页(3)博客编辑页,用户可以在这里进行博客的编写(4)登陆页2。博客系统要实现的功能(1)实现博客列表:让页面从服务器上拿到博客数据(数据库)(2)实现博客详......
  • KDNuggets-博客中文翻译-十四-
    KDNuggets博客中文翻译(十四)原文:KDNuggets协议:CCBY-NC-SA4.0数据科学家职位薪资分析原文:www.kdnuggets.com/2023/04/data-scientist-job-salaries-analysis.html图片来源:TimaMiroshnichenko数据科学和机器学习在运动、艺术、空间、医学、医疗保健等多个领域越来越受......
  • 博客园众包平台
    众包平台是博客园2024年重新开始的商业化进程中正在探索的最重要的商业模式。目前一边在融资,一边在召集早期合作开发者,一边在介绍一些单子给合作开发者。当前已召集2000多位很有经验的合作开发者,其中不少有十年以上的工作经验,其中不少是园子的老用户。如果您有软件开发外包需求......
  • 博客园 - 2024年10月24日之前使用的主题
     概览 配置01||基本设置02||代码高亮03||侧边栏公告04||页面定制CSS代码页面定制css代码/*动态星系*/@keyframesspin3D{from{transform:rotate3d(0.5,0.5,0.5,360deg)}to{transform:rotate3d(0deg)}}#loading{height:100%;background-color:#1d2630......
  • 博客搭建之路:hexo搜索引擎收录
    hexo搜索引擎收录hexo版本5.0.2npm版本6.14.7next版本7.8.0写博客的目的肯定不是就只有自己能看到,想让更多的人看到就需要可以让搜索引擎来收录对应的文章。hexo支持生成站点地图sitemap在hexo下的_config.yml中配置站点地图url:https://zhhll.icusitemap:url:htt......
  • 配合hexo搭建个人博客
    1,修改为淘宝yumnpmconfigsetregistryhttps://registry.npmmirror.com2,查看是否换成功npmconfiggetregistry3,安装hexo框架anpminstallhexo-cli-g4,查看hexo框架安装是否成功,成功会回显一长串版本号hexo-v5,拉取hexo,多次尝试,第一次可能拉去不成功。或者,使用管理......
  • 博客初始设置
    声明本文属于本人《从零开始美化博客》系列,系列详细信息请访问我的博客。你可以在我的github仓库中查看完整代码,或是在文末查看本文相关代码,相关代码遵循MIT协议,你可以在github仓库下的LICENSE文件查看详细协议。你可以在这里预览最新进展中的博客页面。Step\(1\)......