Java学习笔记2024/2/20

今日作业:

题目1

完成课堂上所有练习

package test.test1;
​
import java.util.Random;
​
public class Test3 {
​public static void main(String[] args) {//键盘输入任意字符串,打乱里面的内容
​//1.键盘输入任意字符串String str = "abcdefg";
​//2.打乱里面的内容//修改字符串里面的内容://1.subString//2.变成字符数组char[] arr = str.toCharArray();//['a','b','c','d','e','f','g']
​//3.打乱数组里面的内容//从0索引开始,跟一个随机索引进行位置的交换//当数组里面的每一个元素都跟一个随机索引进行交换完毕之后,那么内容就打乱了for (int i = 0; i < arr.length; i++) {Random random = new Random();int r = random.nextInt(str.length());char temp = arr[i];arr[i] = arr[r];arr[r] = temp;}
​//4.把字符数组再变回字符串String result = new String(arr);
​System.out.println(result);}}
package test.test2;
​
import java.util.Random;
​
public class Test4 {public static void main(String[] args) {/*生成验证码内容:可以是小写字母,也可以是大写字母,还可以是数字规则:长度为5内容中是四位字母,1位数字。其中数字只有1位,但是可以出现在任意的位置。*/
​//1.可以把所有的大写字母,小写字母都放到一个数组当中char[] arr = new char[52];//a-z  A-Zfor (int i = 0; i < arr.length; i++) {
​if (i <= 25) {arr[i] = (char) ('a' + i);//强制转换} else {arr[i] = (char) ('A' + i - 26);}
​}
​Random random = new Random();char[] k = new char[4];//2.从数组中随机获取4次for (int i = 0; i < arr.length; i++) {int r = random.nextInt(52);//3~52,52-3=49,49+1=(50),0~(50) + 3 = 3 ~ (50)k[i] = arr[r];if (i == 3) {break;}}String re = "";for (int i = 0; i < k.length; i++) {re = re + k[i];}//3.生成一个0~9之间的随机数拼接到最后//ACFG7//思考,我们把7放到前面,修改了字符串的内容//把生成的验证码先变成一个字符数组//再让最后一个元素跟前面的随机位置的元素进行交换//交换完毕之后再变成字符串就可以了。int num = random.nextInt(10);re = re + num;System.out.println(re);
​//把生成的验证码先变成一个字符数组char[] brr = re.toCharArray();for (int i = 0; i < brr.length-1;) {int ran = random.nextInt(4);//0~3,3-0=3,3+1=(4),0~(4)+0,0~(4)char temp = brr[brr.length-1];brr[brr.length-1] = brr[ran];brr[ran] = temp;break;}for (int i = 0; i < brr.length; i++) {System.out.println(brr[i]);}
​//交换完毕之后再变成字符串就可以了。String result = new String(brr);System.out.println(result);}}
package test.test1;
​
public class Test5 {public static void main(String[] args) {/* 给定两个以字符串形式表示的非负整数num1和num2,返回num1和num2的乘积,它们的乘积也表示为字符串形式。注意:需要用已有的知识完成。*/
​//不需要考虑乘积过大之后的结果//就认为乘积一定是小于int的最大值的
​
​String num1 = "12345";String num2 = "123";
​//1.把num1和num2变成对应的整数才可以//"123456789"//先遍历字符串依次得到每一个字符 '1'  '2'  '3'  '4'  '5'  '6'  '7'  '8'  '9'//再把字符变成对应的数字即可     1    2    3     4    5    6    7    8    9//把每一个数字组合到一起 123456789int re1 = 0;re1 = getRe(num1, re1);System.out.println(re1);int re2 = 0;re2 = getRe(num2, re2);System.out.println(re2);//2.利用整数进行相乘int re = re1 * re2;System.out.println(re);
​//3.可以把整数变成字符串//+""String s = "";s = s + re;System.out.println(s);
​}
​private static int getRe(String num, int re) {for (int i = 0; i < num.length(); i++) {char n = num.charAt(i);//可以自己遍历字符串,也可以转化为字符数组再遍历int s = changeNumber(n);re = re * 10 + s;}return re;}
​public static int changeNumber(char number) {int str = switch (number) {case '1' -> 1;case '2' -> 2;case '3' -> 3;case '4' -> 4;case '5' -> 5;case '6' -> 6;case '7' -> 7;case '8' -> 8;case '9' -> 9;default -> -1;};return str;
​}
​
}
package test.test1;
​
public class Test6 {
​public static void main(String[] args) {/* 给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中最后一个单词的长度。单词是指仅由字母组成、不包含任何空格字符的最大子字符串。
​示例 1:输入:s = "Hello World“   输出:5解释:最后一个单词是“World”,长度为5。
​示例 2:输入:s = "   fly me   to   the moon" 输出:4解释:最后一个单词是“moon”,长度为4。
​示例 3:输入:s = "luffy is still joyboy" 输出:6解释:最后一个单词是长度为6的“joyboy”。*/
​//倒着遍历//直到遇到空格为止   //字符串的比较用equeals,字符的比较用==//那么遍历的次数就是单词的长度
​String s = "   fly me   to   the moon";
​int count = 0;char c = ' ';for (int i = s.length() - 1; i >= 0; i--) {char n = s.charAt(i);if (n == c) {  //字符不能够跟字符串比较,要化为一个类型break;}count++;
​}System.out.println(count);
​}
​
}

题目2

键盘输入任意字符串,打乱里面的内容

训练目标

随机数类Random相关API、字符串相关API

训练提示

1、字符串是不可变的

2、如果要变化需要变成字符数组

3、调整完毕之后再变回字符串

参考答案

package test.test1;
​
import java.util.Random;
​
public class Test3 {
​public static void main(String[] args) {//键盘输入任意字符串,打乱里面的内容
​//1.键盘输入任意字符串String str = "abcdefg";
​//2.打乱里面的内容//修改字符串里面的内容://1.subString//2.变成字符数组char[] arr = str.toCharArray();//['a','b','c','d','e','f','g']
​//3.打乱数组里面的内容//从0索引开始,跟一个随机索引进行位置的交换//当数组里面的每一个元素都跟一个随机索引进行交换完毕之后,那么内容就打乱了for (int i = 0; i < arr.length; i++) {Random random = new Random();int r = random.nextInt(str.length());char temp = arr[i];arr[i] = arr[r];arr[r] = temp;}
​//4.把字符数组再变回字符串String result = new String(arr);
​System.out.println(result);}}

题目3

训练目标:

生成验证码

内容:可以是小写字母,也可以是大写字母,还可以是数字

规则:

长度为5
​
内容中是四位字母,1位数字。
​
其中数字只有1位,但是可以出现在任意的位置。

参考答案

package test.test1;
​
import java.util.Random;
​
public class Test4 {public static void main(String[] args) {/*生成验证码内容:可以是小写字母,也可以是大写字母,还可以是数字规则:长度为5内容中是四位字母,1位数字。其中数字只有1位,但是可以出现在任意的位置。*/
​//1.可以把所有的大写字母,小写字母都放到一个数组当中char[] arr = new char[52];//a-z  A-Zfor (int i = 0; i < arr.length; i++) {
​if (i <= 25) {arr[i] = (char) ('a' + i);//强制转换} else {arr[i] = (char) ('A' + i - 26);}
​}
​Random random = new Random();char[] k = new char[4];//2.从数组中随机获取4次for (int i = 0; i < arr.length; i++) {int r = random.nextInt(52);//3~52,52-3=49,49+1=(50),0~(50) + 3 = 3 ~ (50)k[i] = arr[r];if (i == 3) {break;}}String re = "";for (int i = 0; i < k.length; i++) {re = re + k[i];}//3.生成一个0~9之间的随机数拼接到最后//ACFG7//思考,我们把7放到前面,修改了字符串的内容//把生成的验证码先变成一个字符数组//再让最后一个元素跟前面的随机位置的元素进行交换//交换完毕之后再变成字符串就可以了。int num = random.nextInt(10);re = re + num;System.out.println(re);
​//把生成的验证码先变成一个字符数组char[] brr = re.toCharArray();for (int i = 0; i < brr.length-1;) {int ran = random.nextInt(4);//0~3,3-0=3,3+1=(4),0~(4)+0,0~(4)char temp = brr[brr.length-1];brr[brr.length-1] = brr[ran];brr[ran] = temp;break;}for (int i = 0; i < brr.length; i++) {System.out.println(brr[i]);}
​//交换完毕之后再变成字符串就可以了。String result = new String(brr);System.out.println(result);}}

题目4

请编写程序,由键盘录入一个字符串,统计字符串中英文字母和数字分别有多少个。比如:Hello12345World中字母:10个,数字:5个。

训练目标

字符串遍历

训练提示

1、键盘录入一个字符串,用 Scanner 实现 2、要统计两种类型的字符个数,需定义两个统计变量,初始值都为0 3、遍历字符串,得到每一个字符 4、判断该字符属于哪种类型,然后对应类型的统计变量+1,判断字母时需要考虑大小写,条件比较复杂,怎样做才能使判断更简单呢?

训练步骤

1、创建键盘录入Scanner对象,使用nextLine方法接收输入的字符串。

2、为方便后续判断,使用String的toLowerCase方法,将字符串中的字符都转为小写。

3、需定义两个统计变量,初始值都为0

4、遍历字符串,得到每一个字符

5、判断该字符属于哪种类型,然后对应类型的统计变量+1,次数判断英文字母时只需判断小写即可。

参考答案

package test.test4;
​
import java.util.Scanner;
​
public class test4 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("输入一个字符串");//比如:Hello12345World中字母:10个,数字:5个。String str = scanner.nextLine();//next()、nextInt()、nextDouble()这三个配套使用。//nextLine()单独使用。str = str.toLowerCase();System.out.println(str);
​int count1 = 0;int count2 = 0;for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);if (c >= '0' && c <= '9') {count1++;}
​if(c >= 'a' && c <= 'z'){count2++;}
​}
​System.out.println("数字有:" + count1 + "个");System.out.println("英文字母有:" + count2 + "个");}
​
}
​

题目5

请定义一个方法用于判断一个字符串是否是对称的字符串,并在主方法中测试方法。例如:"abcba"、"上海自来水来自海上"均为对称字符串。

训练目标

字符串的反转功能,判断是否相等功能

训练提示

1、判断是否对称,方法的返回值是什么类型?参数列表是什么?

2、怎样判断对称呢?如果可以将字符串反转,反转后发现跟原来的字符串完全一样,不就可以判断出来了吗,那么哪个类有字符串的反转功能呢?

训练步骤

1、定义方法,返回值类型为boolean,参数列表为String类型的一个参数。

2、将字符串转换为StringBuilder类型,调用StringBuilder的reverse()方法将字符串反转。

3、将反转后的字符串再转回String类型,并与原字符串比较,如果相等,返回true,否则返回false

4、在主方法中,定义一个字符串,调用方法测试结果。

参考答案

package test.test5;
​
public class test5 {public static void main(String[] args) {String str = "abcba";boolean re = getFan(str);System.out.println(re);
​}
​public static boolean getFan(String str) {StringBuilder str1 = new StringBuilder(str);String s = str1.reverse().toString();//此时的str1如果不加toString就只是一个容器,容器无法与字符串比较//StringBuilder相当于一个容器,将字符串拿到容器里面进行各种操作,操作完了之后还得重新将字符串拿出来if (s.equals(str)) {return true;} else {return false;}
​}
​
}
​

题目6

我国的居民身份证号码,由由十七位数字本体码和一位数字校验码组成。请定义方法判断用户输入的身份证号码是否合法,并在主方法中调用方法测试结果。规则为:号码为18位,不能以数字0开头,前17位只可以是数字,最后一位可以是数字或者大写字母X。

训练目标

字符串的遍历、判断

训练提示

1、要判断字符串是否符合规则,方法的返回值类型是什么?参数列表是什么?

2、使用String的API,对每种不符合条件的情况作出判断,一旦发现不符合条件就可以结束方法的执行,返回结果了。

3、在主方法中创建键盘录入,调用方法,输入各种数据测试结果。

训练步骤

1、定义方法,返回值类型为boolean表示是否合法,参数列表为String类型的id,表示要判断的数据。

2、对每种不符合条件的情况作出判断

2.1、如果字符串长度不是18,返回false。

2.2、如果字符串以数字"0"开头,返回false。

2.3、遍历字符串,获取每一位字符,判断前17位,如果不是数字,返回false,判断最后一位如果不是数字或者X,返回false

2.4、所以的不符合条件都筛选完成,返回true

3、在主方法中创建键盘录入Scanner对象,调用nextLine()方法,获取用户输入,调用方法,传递参数,查看结果。要多运行几次,判断各种不符合条件的数据。

参考答案

package test.test6;
​
import java.util.Scanner;
​
public class test6 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("输入身份证号");String id = scanner.nextLine();boolean flag = pdId(id);System.out.println(flag);
​}public static boolean pdId(String id) {if (id.length() != 18) {return false;}
​if (id.charAt(0) == '0') {return false;}
​for (int i = 0; i < id.length(); i++) {if (i == id.length() - 1) {
​if ((id.charAt(i) >= '1' && id.charAt(i) <= '9') || id.charAt(i) == 'X') {
​} else {return false;}
​} else {
​if (id.charAt(i) >= '0' && id.charAt(i) <= '9') {
​} else {return false;}
​}
​}
​return true;
​}
​
}
​

题目7

定义一个方法,把 int 数组中的数据按照指定的格式拼接成一个字符串返回,调用该方法,并在控制台输出结果。

要求:

1、如果传递的参数为空,返回null

2、如果传递的数组元素个数为0,返回[]

3、如果数组为int[] arr = {1,2,3}; ,执行方法后的输出结果为:[1, 2, 3]

训练目标

字符串的拼接

训练提示

1、定义方法的返回值是什么?参数列表是什么?

2、如果不做判断就对数组进行遍历,那么如果数组对象为空,会报出异常,怎样避免空指针异常呢?

3、拼接字符串必然涉及到频繁改变,该采用可变的字符序列StringBuilder比较好

4、遍历数组,按照题目格式拼接数组中的元素。

5、将字符串返回

6、在主方法中定义数组,并调用方法,打印结果

训练步骤

1、定义方法返回值类型:String,参数:int[] arr

2、判断对象如果为null,直接返回null

3、创建StringBuilder对象

4、遍历数组,按照要求进行拼接数组元素,如果不是最后一个元素,还要拼接逗号和空格

5、将StringBuilder转为String返回

6、在主方法中定义数组,并调用方法,打印结果

参考答案

package test.test7;
​
public class test7 {public static void main(String[] args) {int[] arr = {1,2,3};String str = getStr(arr);System.out.println(str);}
​public static String getStr(int[] arr) {if (arr == null) {return null;}StringBuilder sb = new StringBuilder();sb.append("[");for (int i = 0; i < arr.length; i++) {if (i == arr.length-1) {sb.append(arr[i]);}else {sb.append(arr[i]+",");}}sb.append("]");return sb.toString();
​}
​
}
​

题目8(扩展)

在String类的API中,有如下两个方法:

// 查找参数字符串"Java"在调用方法的字符串中第一次出现的索引,如果不存在,返回-1
public int indexOf(String "Java")
​
// 截取字符串,从索引beginIndex(包含)开始到字符串的结尾
public String substring(int beginIndex)

请仔细阅读API中这两个方法的解释,完成如下需求。

现有如下文本:"Java语言是面向对象的,Java语言是健壮的,Java语言是安全的,Java是高性能的,Java语言是跨平台的"。请编写程序,统计该文本中"Java"一词出现的次数。

训练目标

String类API的灵活使用

训练提示

1、要找的子串是否存在,如果存在获取其出现的位置。这个可以使用indexOf完成。 2、如果找到了,那么就记录出现的位置并在剩余的字符串中继续查找该子串,而剩余字符串的起始位是出现位置再加上子串的长度。

3、以此类推,通过循环完成查找,如果找不到就是-1,每次找到用计数器记录次数。

训练步骤

1、定义方法,返回值int表示次数,参数列表两个字符串,第一个表示在哪个字符串中查找,第二个表示要查找的目标子串

2、定义统计变量表示次数。

3、定义索引变量,表示每次找到子串出现的索引。

4、定义循环,判断条件为在字符串中找到了目标子串,使用indexOf实现。

5、如果找到的索引不是-1,在循环中,统计变量累加。

6、把查找过的部分剪切掉,从找到的索引+子串长度的位置开始截取,使用substring实现。

7、将统计变量返回

8、在主方法中,定义字符串表示题目中的文本,定义字符串表示要查找的子串,调用方法,获取结果。

参考答案

package test.test8;
​
public class test8 {public static void main(String[] args) {String str1 = "Java语言是面向对象的,Java语言是健壮的,Java语言是安全的,Java是高性能的,Java语言是跨平台的";String str2 = "Java";int count = getCount(str1, str2);System.out.println(count);}
​public static int getCount(String str1, String str2) {int count = 0;int index;while ((index = str1.indexOf(str2)) != -1) {count++;str1 = str1.substring(index + str2.length());}return count;
​}
​
}
​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/692220.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安卓adb调试备忘录

由于 MAC 的 USB 口全被占用着&#xff0c;采用无线连接刚方便&#xff0c;记录一下&#xff0c;以防忘记~ ADB原理 adb devices -l ## 列出连接的设备adb tcpip [端口号] adb tcpip 6666 # 将当前已连接USB上的Mobile端切换为TCP/IP模式&#xff0c;以6666端口进行监听. adb…

你真的了解—————NumPy吗

&#x1f308;个人主页&#xff1a;小田爱学编程 &#x1f525; 系列专栏&#xff1a;opencv &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于IT的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎来到小田代码世界~ &#x1f601; 喜欢的…

【大厂AI课学习笔记】【2.2机器学习开发任务实例】(8)模型训练

好吧&#xff0c;搞了半天&#xff0c;都是围绕数据在干活&#xff0c;这也就验证了&#xff0c;我们说的&#xff0c;数据准备等工作&#xff0c;要占到机器学习项目一半以上的工作量和时间。而且数据决定了模型的天花板&#xff0c;算法只是去达到上限。 我们今天来学习模型…

Java实现Redis延时队列

“如何实现Redis延时队列”这个面试题应该也是比较常见的&#xff0c;解答如下&#xff1a; 使用sortedset&#xff08;有序集合&#xff09; &#xff0c;拿时间戳作为 score &#xff0c;消息内容作为key 调用 zadd 来生产消息&#xff0c;消费者用zrangebyscore 指令获取 N …

暴力枚举刷题2

题目来源&#xff1a;烤鸡 - 洛谷 参考书目&#xff1a;参考书籍&#xff1a;《深入浅出程序设计竞赛&#xff08;基础篇&#xff09;》 解题思路&#xff1a;这道题可以用暴力枚举的方法解决&#xff0c;用10层for循环&#xff0c;再if判断就能找到所有符合的情况。因为 n 的…

2、windows环境下vscode开发c/c++环境配置(一)

前言&#xff1a;VSCode是微软出的一款轻量级编辑器&#xff0c;它本身只是一款文本编辑器而已&#xff0c;并不是一个集成开发环境(IDE)&#xff0c;几乎所有功能都是以插件扩展的形式所存在的。因此&#xff0c;我们想用它编程&#xff0c;不只是把vscode下载下来就行&#x…

数据分析 — 电商用户分析和用户 RFM 模型

目录 一、电商用户分析1、数据字段信息2、数据读取3、数据清洗4、可视化分析1、每年销售额的增长情况2、各个地区分店的销售额3、每个分店每一年的销售额4、销售淡旺季5、新增用户 二、RFM 模型1、RFM 模型的三个维度2、RFM 的客户类型标签3、RFM 模型的二分法思想4、代码 一、…

【C#小知识】c#中的delegate(委托)和event(事件)

今天来介绍一下delegate和event。delegate在c#中可以定义一个函数类型&#xff0c;可以将函数作为一个对象来使用。event在c#中则可以看做一个函数的集合&#xff0c;event中包含了一个或多个函数。 delegate using System;public class MyClass {//定义委托public delegate v…

计网day6

七 应用层 7.1 网络应用模型 7.2 DNS系统 7.3 文件传输协议FTP 7.4 电子邮件 7.5 万维网和HTTP协议

细数高德地图的发展史

根据2023年自然资源部公布的名单显示&#xff0c;以下公司通过“地图甲级测绘资质”换证审核&#xff0c;也就意味着&#xff0c;以下这些公司可以继续从事电子地图的采集和制作、商业合作等相关业务。 而这一点&#xff0c;对于以电子地图导航为主要业务支撑的企业至关重要。…

Sql Server 视图

USE [数据库名称] GO /****** Object: View [dbo].[视图名称] Script Date: 2024/2/19 10:08:13 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE VIEW [dbo].[视图名称&#xff1a;V_XXXXX] AS SELECT FILED1, FILED2, FILED3, FILED4 FROM dbo.表名…

【编程题】跳石板

跳石板 分析后可知 要在众多解中寻找最优解 因此用动态规划 比如&#xff1a; 4-6只需跳一步&#xff0c;而6-8也只需一步&#xff0c;因此在刚才跳了一步的基础上再加1 8到10一步&#xff0c;8到12一步&#xff0c;9到12一步&#xff0c;8-10-12两步&#xff0c;因此到12位置…

Hash哈希

当需要快速查询数据的记录时&#xff1a; 手动按某规则为数据建立索引&#xff0c;利用数组维护数据若1中需要开大数组爆内存&#xff0c;利用官方库的Hash集合&#xff0c;可以将最好情况下的时间复杂度优化到O(1)避免T和M。 1. LC 2036 最大好子数组和 VP双周赛123T3。一开…

新增长100人研讨会:快消零售专场探讨招商加盟数字化转型实战

2024年2月2日下午&#xff0c;一场由纷享销客与杨国福集团联合主办的招商加盟数字化转型研讨会在上海成功举办。本次研讨会汇聚了众多快消零售业界的领军人物&#xff0c;共同探讨行业未来的新增长点。 会议伊始&#xff0c;杨国福集团数字化中心负责人王林林发表了主题演讲&a…

Redis-面试题

一、基础 1、什么是Redis C语言编写,基于key-value存储的nosql开源内存数据库内存存储、数据结构优化,高性能一般用于应用和数据库之间的分布式缓存中间件提供主从复制+哨兵、集群的方式实现高可用,在redis集群中通过hash槽的方式实现数据分片,进一步提升性能和可扩展性2、…

使用Nginx或者Fiddler快速代理调试

1 背景问题 在分析业务系统程序问题时,存在服务系统环境是其它部门或者其它小组搭建或运维的,并且现在微服务时代,服务多且复杂,在个人机器上搭建起如此环境,要么费事费力,要么不具备充足条件。 急需有一种方法或者工具可以快速辅助调试定位分析问题。本文下面介绍代理方…

算法-递归

题目&#xff1a;打印中序遍历指定节点的后续节点 思路&#xff1a;两种情况当前节点右子树是否为null&#xff0c;如果不是返回右子树最左非空子节点&#xff0c;否则往上找&#xff0c;直到父节点为空或者当前节点是父节点的左子树&#xff0c;返回父节点 public class Code…

LeetCode面试题 17.24. Max Submatrix LCCI——压缩数组+动态规划

文章目录 一、题目二、题解 一、题目 Given an NxM matrix of positive and negative integers, write code to find the submatrix with the largest possible sum. Return an array [r1, c1, r2, c2], where r1, c1 are the row number and the column number of the subma…

2.12:C语言测试题

1.段错误&#xff1a;str指向NULL&#xff0c;不能把"hello world" 复制给NULL 2.报错&#xff1a;返回局部变量&#xff0c;本函数结束&#xff0c;非法访问&#xff0c;不一定输出hello world 3.地址传递&#xff0c;修改str&#xff0c;正常输出hello 4.可以输出…

npm ERR! code CERT_HAS_EXPIRED:解决证书过期问题

转载&#xff1a;npm ERR! code CERT_HAS_EXPIRED&#xff1a;解决证书过期问题_npm err! code cert_has_expired npm err! errno cert-CSDN博客 npm config set registry http://registry.cnpmjs.org npm config set registry http://registry.npm.taobao.org