前言:

语音评测(SpeechEvaluator):
通过智能语音技术自动对发音水平进行评价、发音错误、缺陷进行定位和问题分析。目前评音评测提供汉语、英语两种语言的评测,支持单字(汉语专有)、词语 和句子朗读三种题型。

效果图:

1、IseActivity.java

public class IseActivity extends AppCompatActivity implements View.OnClickListener {private static final String TAG = "IseActivity";private EditText mEvaTextEditText;private EditText mResultEditText;private Button mIseStartButton;private Button iseLanguages, iseTopic, iseResultLevel;private EditText iseStartTime, iseEndTime, iseTime;private String mLastResult;private SpeechEvaluator mIse;//切换(汉语、句子、等级)private String languageType = "zh_cn", topicType = "read_sentence", resultLevelType = "complete";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_ise);mIse = SpeechEvaluator.createEvaluator(this, null);initUI();setEvaText();}private void initUI() {mEvaTextEditText = this.findViewById(R.id.ise_eva_text);mResultEditText = this.findViewById(R.id.ise_result_text);mIseStartButton = this.findViewById(R.id.ise_start);iseLanguages = this.findViewById(R.id.ise_languages);iseTopic = this.findViewById(R.id.ise_topic);iseResultLevel = this.findViewById(R.id.ise_result_level);iseStartTime = this.findViewById(R.id.ise_start_time);iseEndTime = this.findViewById(R.id.ise_end_time);iseTime = this.findViewById(R.id.ise_time);mIseStartButton.setOnClickListener(this);iseLanguages.setOnClickListener(this);iseTopic.setOnClickListener(this);iseResultLevel.setOnClickListener(this);findViewById(R.id.ise_parse).setOnClickListener(this);findViewById(R.id.ise_stop).setOnClickListener(this);findViewById(R.id.ise_cancel).setOnClickListener(this);}@Overridepublic void onClick(View view) {if (null == mIse) {// 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688showToast("创建对象失败,请确认 libmsc.so 放置正确,且有调用 createUtility 进行初始化");return;}switch (view.getId()) {case R.id.ise_start:if (mIse == null) {return;}String evaText = mEvaTextEditText.getText().toString();mLastResult = null;mResultEditText.setText("");mResultEditText.setHint("请朗读以上内容");mIseStartButton.setEnabled(false);setParams();int ret = mIse.startEvaluating(evaText, null, mEvaluatorListener);//以下方法为通过直接写入音频的方式进行评测业务/*if (ret != ErrorCode.SUCCESS) {showTip("识别失败,错误码:" + ret);} else {showTip(getString(R.string.text_begin_ise));byte[] audioData = FucUtil.readAudioFile(IseDemo.this,"isetest.wav");if(audioData != null) {//防止写入音频过早导致失败try{new Thread().sleep(100);}catch (InterruptedException e) {Log.d(TAG,"InterruptedException :"+e);}mIse.writeAudio(audioData,0,audioData.length);mIse.stopEvaluating();}}*/break;case R.id.ise_parse:// 解析最终结果if (!TextUtils.isEmpty(mLastResult)) {XmlResultParser resultParser = new XmlResultParser();Result result = resultParser.parse(mLastResult);if (null != result) {mResultEditText.setText(result.toString());} else {showToast("解析结果为空");}}break;case R.id.ise_stop:if (mIse.isEvaluating()) {mResultEditText.setHint("评测已停止,等待结果中...");mIse.stopEvaluating();}break;case R.id.ise_cancel:mIse.cancel();mIseStartButton.setEnabled(true);mResultEditText.setText("");mResultEditText.setHint("请点击“开始评测”按钮");mLastResult = null;break;case R.id.ise_languages:if (languageType.equals("zh_cn")) {languageType = "en_us";iseLanguages.setText("语种:英语");} else {languageType = "zh_cn";iseLanguages.setText("语种:汉语");}setEvaText();break;case R.id.ise_topic:if (topicType.equals("read_sentence")) {topicType = "read_word";iseTopic.setText("题型:词语");} else if (topicType.equals("read_word")) {topicType = "read_syllable";iseTopic.setText("题型:单词");} else {topicType = "read_sentence";iseTopic.setText("题型:句子");}setEvaText();break;case R.id.ise_result_level:if (resultLevelType.equals("complete")) {resultLevelType = "plain";iseResultLevel.setText("等级:plain");} else {resultLevelType = "complete";iseResultLevel.setText("等级:complete");}setEvaText();break;default:}}// 设置评测试题private void setEvaText() {String text = "";if ("en_us".equals(languageType)) {if ("read_word".equals(topicType)) {text = getString(R.string.text_en_word);} else if ("read_sentence".equals(topicType)) {text = getString(R.string.text_en_sentence);}} else {// 中文评测if ("read_syllable".equals(topicType)) {text = getString(R.string.text_cn_syllable);} else if ("read_word".equals(topicType)) {text = getString(R.string.text_cn_word);} else if ("read_sentence".equals(topicType)) {text = getString(R.string.text_cn_sentence);}}mEvaTextEditText.setText(text);mResultEditText.setText("");mLastResult = null;mResultEditText.setHint("请点击“开始评测”按钮");}private void setParams() {// 设置评测语言mIse.setParameter(SpeechConstant.LANGUAGE, languageType);// 设置需要评测的类型mIse.setParameter(SpeechConstant.ISE_CATEGORY, topicType);// 设置结果等级(中文仅支持complete)mIse.setParameter(SpeechConstant.RESULT_LEVEL, resultLevelType);mIse.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");// 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理mIse.setParameter(SpeechConstant.VAD_BOS, iseStartTime.getText().toString());// 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音mIse.setParameter(SpeechConstant.VAD_EOS, iseEndTime.getText().toString());// 语音输入超时时间,即用户最多可以连续说多长时间;(-1无超时)mIse.setParameter(SpeechConstant.KEY_SPEECH_TIMEOUT, iseTime.getText().toString());mIse.setParameter(SpeechConstant.AUDIO_FORMAT_AUE, "opus");// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限mIse.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");mIse.setParameter(SpeechConstant.ISE_AUDIO_PATH, Environment.getExternalStorageDirectory().getAbsolutePath() + "/msc/helloword_ise.wav");//通过writeaudio方式直接写入音频时才需要此设置//mIse.setParameter(SpeechConstant.AUDIO_SOURCE,"-1");}// 评测监听接口private EvaluatorListener mEvaluatorListener = new EvaluatorListener() {@Overridepublic void onResult(EvaluatorResult result, boolean isLast) {Log.e(TAG, "evaluator result :" + isLast);if (isLast) {StringBuilder builder = new StringBuilder();builder.append(result.getResultString());if (!TextUtils.isEmpty(builder)) {mResultEditText.setText(builder.toString());}mIseStartButton.setEnabled(true);mLastResult = builder.toString();showToast("评测结束");}}@Overridepublic void onError(SpeechError error) {mIseStartButton.setEnabled(true);if (error != null) {showToast("error:" + error.getErrorCode() + "," + error.getErrorDescription());mResultEditText.setText("");mResultEditText.setHint("请点击“开始评测”按钮");} else {Log.e(TAG, "evaluator over");}}@Overridepublic void onBeginOfSpeech() {// 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入Log.e(TAG, "onBeginOfSpeech: evaluator begin");}@Overridepublic void onEndOfSpeech() {// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入Log.e(TAG, "onEndOfSpeech: evaluator stoped");}@Overridepublic void onVolumeChanged(int volume, byte[] data) {showToast("当前音量:" + volume);Log.e(TAG, "onVolumeChanged: 返回音频数据" + data.length);}@Overridepublic void onEvent(int eventType, int arg1, int arg2, Bundle obj) {// 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因//    if (SpeechEvent.EVENT_SESSION_ID == eventType) {//        String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);//        Log.d(TAG, "session id =" + sid);// }}};/*** 展示吐司*/private void showToast(final String str) {Toast.makeText(this, str, Toast.LENGTH_SHORT).show();}@Overrideprotected void onResume() {// 开放统计 移动数据统计分析//FlowerCollector.onResume(IseDemo.this);//FlowerCollector.onPageStart(TAG);super.onResume();}@Overrideprotected void onPause() {// 开放统计 移动数据统计分析//FlowerCollector.onPageEnd(TAG);//FlowerCollector.onPause(IseDemo.this);super.onPause();}@Overrideprotected void onDestroy() {super.onDestroy();if (null != mIse) {mIse.destroy();mIse = null;}}
}

布局文件activity_ise.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center_horizontal"android:orientation="vertical"android:paddingLeft="10dp"android:paddingRight="10dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:text="讯飞评测示例"android:textSize="30sp" /><EditTextandroid:id="@+id/ise_eva_text"android:layout_width="match_parent"android:layout_height="120dp"android:layout_marginBottom="5dp"android:gravity="top|left"android:textSize="20sp" /><EditTextandroid:id="@+id/ise_result_text"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:gravity="top|left"android:hint="请点击“开始评测”按钮"android:textSize="16sp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:gravity="center_vertical"android:orientation="horizontal"><Buttonandroid:id="@+id/ise_languages"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="语种:汉语"android:textSize="16sp" /><Buttonandroid:id="@+id/ise_topic"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="题型:句子"android:textSize="16sp" /><Buttonandroid:id="@+id/ise_result_level"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="等级:complete"android:textSize="16sp" /></LinearLayout><EditTextandroid:id="@+id/ise_start_time"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="前端超时:(默认:5000ms)"android:inputType="number"android:padding="10dp"android:textSize="20sp" /><EditTextandroid:id="@+id/ise_end_time"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="后端超时:(默认:1800ms)"android:inputType="number"android:padding="10dp"android:textSize="20sp" /><EditTextandroid:id="@+id/ise_time"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="评测超时:(默认:-1无超时,单位同上)"android:inputType="number"android:padding="10dp"android:textSize="20sp" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="修改数值后需重新开始评测"android:textSize="15sp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:layout_marginBottom="2dp"android:gravity="center_horizontal"android:orientation="horizontal"><Buttonandroid:id="@+id/ise_start"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="开始评测"android:textSize="20sp" /><Buttonandroid:id="@+id/ise_stop"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="停止评测"android:textSize="20sp" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:layout_marginBottom="2dp"android:gravity="center_horizontal"android:orientation="horizontal"><Buttonandroid:id="@+id/ise_cancel"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="取消评测"android:textSize="20sp" /><Buttonandroid:id="@+id/ise_parse"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="结果解析"android:textSize="20sp" /></LinearLayout></LinearLayout>

2、工具类XmlResultParser.java(Demo中也有):

public class XmlResultParser {public Result parse(String xml) {if (TextUtils.isEmpty(xml)) {return null;}XmlPullParser pullParser = Xml.newPullParser();try {InputStream ins = new ByteArrayInputStream(xml.getBytes());pullParser.setInput(ins, "utf-8");FinalResult finalResult = null;int eventType = pullParser.getEventType();while (XmlPullParser.END_DOCUMENT != eventType) {switch (eventType) {case XmlPullParser.START_TAG:if ("FinalResult".equals(pullParser.getName())) {// 只有一个总分的结果finalResult = new FinalResult();} else if ("ret".equals(pullParser.getName())) {finalResult.ret = getInt(pullParser, "value");} else if ("total_score".equals(pullParser.getName())) {finalResult.total_score = getFloat(pullParser, "value");} else if ("xml_result".equals(pullParser.getName())) {// 详细结果return parseResult(pullParser);}break;case XmlPullParser.END_TAG:if ("FinalResult".equals(pullParser.getName())) {return finalResult;}break;default:break;}eventType = pullParser.next();}} catch (XmlPullParserException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return null;}private Result parseResult(XmlPullParser pullParser) {Result result = null;// <rec_paper>标签是否已扫描到boolean rec_paperPassed = false;Sentence sentence = null;Word word = null;Syll syll = null;Phone phone = null;int eventType;try {eventType = pullParser.getEventType();while (XmlPullParser.END_DOCUMENT != eventType) {switch (eventType) {case XmlPullParser.START_TAG:if ("rec_paper".equals(pullParser.getName())) {rec_paperPassed = true;} else if ("read_syllable".equals(pullParser.getName())) {if (!rec_paperPassed) {result = new ReadSyllableResult();} else {readTotalResult(result, pullParser);}} else if ("read_word".equals(pullParser.getName())) {if (!rec_paperPassed) {result = new ReadWordResult();String lan = getLanguage(pullParser);result.language = (null == lan) ? "cn" : lan;} else {readTotalResult(result, pullParser);}} else if ("read_sentence".equals(pullParser.getName()) ||"read_chapter".equals(pullParser.getName())) {if (!rec_paperPassed) {result = new ReadSentenceResult();String lan = getLanguage(pullParser);result.language = (null == lan) ? "cn" : lan;} else {readTotalResult(result, pullParser);}} else if ("sentence".equals(pullParser.getName())) {if (null == result.sentences) {result.sentences = new ArrayList<Sentence>();}sentence = createSentence(pullParser);} else if ("word".equals(pullParser.getName())) {if (null != sentence && null == sentence.words) {sentence.words = new ArrayList<Word>();}word = createWord(pullParser);} else if ("syll".equals(pullParser.getName())) {if (null != word && null == word.sylls) {word.sylls = new ArrayList<Syll>();}syll = createSyll(pullParser);} else if ("phone".equals(pullParser.getName())) {if (null != syll && null == syll.phones) {syll.phones = new ArrayList<Phone>();}phone = createPhone(pullParser);}break;case XmlPullParser.END_TAG:if ("phone".equals(pullParser.getName())) {syll.phones.add(phone);} else if ("syll".equals(pullParser.getName())) {word.sylls.add(syll);} else if ("word".equals(pullParser.getName())) {sentence.words.add(word);} else if ("sentence".equals(pullParser.getName())) {result.sentences.add(sentence);} else if ("read_syllable".equals(pullParser.getName())|| "read_word".equals(pullParser.getName())|| "read_sentence".equals(pullParser.getName())) {return result;}break;default:break;}eventType = pullParser.next();}} catch (XmlPullParserException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return result;}private void readTotalResult(Result result, XmlPullParser pullParser) {result.beg_pos = getInt(pullParser, "beg_pos");result.end_pos = getInt(pullParser, "end_pos");result.content = getContent(pullParser);result.total_score = getFloat(pullParser, "total_score");result.time_len = getInt(pullParser, "time_len");result.except_info = getExceptInfo(pullParser);result.is_rejected = getIsRejected(pullParser);}private Phone createPhone(XmlPullParser pullParser) {Phone phone;phone = new Phone();phone.beg_pos = getInt(pullParser, "beg_pos");phone.end_pos = getInt(pullParser, "end_pos");phone.content = getContent(pullParser);phone.dp_message = getInt(pullParser, "dp_message");phone.time_len = getInt(pullParser, "time_len");return phone;}private Syll createSyll(XmlPullParser pullParser) {Syll syll;syll = new Syll();syll.beg_pos = getInt(pullParser, "beg_pos");syll.end_pos = getInt(pullParser, "end_pos");syll.content = getContent(pullParser);syll.symbol = getSymbol(pullParser);syll.dp_message = getInt(pullParser, "dp_message");syll.time_len = getInt(pullParser, "time_len");return syll;}private Word createWord(XmlPullParser pullParser) {Word word;word = new Word();word.beg_pos = getInt(pullParser, "beg_pos");word.end_pos = getInt(pullParser, "end_pos");word.content = getContent(pullParser);word.symbol = getSymbol(pullParser);word.time_len = getInt(pullParser, "time_len");word.dp_message = getInt(pullParser, "dp_message");word.total_score = getFloat(pullParser, "total_score");word.global_index = getInt(pullParser, "global_index");word.index = getInt(pullParser, "index");return word;}private Sentence createSentence(XmlPullParser pullParser) {Sentence sentence;sentence = new Sentence();sentence.beg_pos = getInt(pullParser, "beg_pos");sentence.end_pos = getInt(pullParser, "end_pos");sentence.content = getContent(pullParser);sentence.time_len = getInt(pullParser, "time_len");sentence.index = getInt(pullParser, "index");sentence.word_count = getInt(pullParser, "word_count");return sentence;}private String getLanguage(XmlPullParser pullParser) {return pullParser.getAttributeValue(null, "lan");}private String getExceptInfo(XmlPullParser pullParser) {return pullParser.getAttributeValue(null, "except_info");}private boolean getIsRejected(XmlPullParser pullParser) {String isRejected = pullParser.getAttributeValue(null, "is_rejected");if (null == isRejected) {return false;}return Boolean.parseBoolean(isRejected);}private String getSymbol(XmlPullParser pullParser) {return pullParser.getAttributeValue(null, "symbol");}private float getFloat(XmlPullParser pullParser, String attrName) {String val = pullParser.getAttributeValue(null, attrName);if (null == val) {return 0f;}return Float.parseFloat(val);}private String getContent(XmlPullParser pullParser) {return pullParser.getAttributeValue(null, "content");}private int getInt(XmlPullParser pullParser, String attrName) {String val = pullParser.getAttributeValue(null, attrName);if (null == val) {return 0;}return Integer.parseInt(val);}
}

将Demo中result文件夹拷贝至项目中,如下图所示:

3、使用到的strings.xml:

<string name="text_en_word">"[word]\napple\nbanana\norange"</string>
<string name="text_en_sentence">"The quick brown fox jumps over the lazy dog."</string>
<string name="text_cn_syllable">"知,痴,是"</string>
<string name="text_cn_word">"磁铁,率领,脆弱,动手,古筝"</string>
<string name="text_cn_sentence">"一座座雪峰插入云霄,峰顶银光闪闪,大大小小的湖泊,像颗颗宝石镶嵌在彩带般的沟谷中。"</string>

Android讯飞语音集成【语音评测3】相关推荐

  1. 讯飞AIUI集成语音语义的21003错误

    昨天尝试着使用了一下科大讯飞的AIUI,主要是使用其中的语音语义理解,在使用的过程中碰到了一个21003的错误,也就是初始化失败.找了好久问题出现在哪里,最后发现是由于自己的粗心大意,就是缺少了这一关 ...

  2. 移动端点击拉起输入_没广告、无捆绑、真清流!讯飞输入法PC版评测:跨屏语音动口不动手...

    原标题:没广告.无捆绑.真清流!讯飞输入法PC版评测:跨屏语音动口不动手 一.前言:等待五年 讯飞输入法PC版终于回来了 大家所熟知的讯飞输入法,最早是在Android和iOS等移动端起家,并凭借强大 ...

  3. Android讯飞语音云语音听写学习

    讯飞语音云语音听写学习 这几天两个舍友都买了iPhone 6S,玩起了"Hey, Siri",我依旧对我的Nexus 5喊着"OK,Google".但种种原因, ...

  4. 讯飞社区android 源码,android 讯飞语音 demo

    [实例简介] android 讯飞语音 demo 博客地址:http://blog.csdn.net/chenshufei2/article/details/8496905 [实例截图] [核心代码] ...

  5. Android 讯飞离线语音听写/离线语音识别SDK

    平台 Android + 讯飞离线语音SDK SDK包 下载路径及方法见讯飞官方SDK文档: 离线语音听写 Android SDK 文档 # 在开发者控制台, 可以直接下载SDK. SDK包中的文件结 ...

  6. 讯飞语音转文字_录音实时转文字就是如此简单 讯飞智能录音笔SR701评测

    对于职场人来讲,信息的记录和整理是件即基础又核心的能力.录音笔无疑是一个全面的及信息记录工具,同时也是被更多职场人士忽略的办公设备,因为每次记录过后,都需要逐句的将录音内容转换成文字进行整理归档,这无 ...

  7. 长话无需短说 讯飞输入法超长语音输入不限时

    原标题:长话无需短说 讯飞输入法超长语音输入不限时 对用户来说,衡量语音输入好坏无外乎两个指标,一个是输入准确率,另一个是识别速度.搭载自然语言理解(NLU)优化模型的讯飞输入法语音识别率提升至98% ...

  8. 【Qbot】6.讯飞文字转语音Api使用/VITS派蒙复读机实现

    该项目计划长期进行维护更新,欢迎star:https://github.com/zstar1003/Qbot 前言 看完流浪地球2之后,萌生了一个想法:我想给机器人完整的一生.作为一个完整的机器人,声 ...

  9. 讯飞小车比赛语音控制(基础)

    讯飞小车比赛语音控制 第一次写这玩意可能写的不咋地,主要也是看了一些网上的资料后面给了连接,千万不要骂人,不行我删掉.谢谢 1.硬件层面 本次比赛所使用的麦克风为ucar小车自带的环形六麦克风阵列,该 ...

最新文章

  1. Maven(插件配置和生命周期的绑定)
  2. Windows 2003 服务器播放FLV的问题解决
  3. [YTU]_2878( 结构体--学生信息排序)
  4. NumPy简明教程(二、数组2)
  5. CNN基础知识(2)
  6. php oracle 配置,关于php:为Windows 64位配置Oracle OCI8
  7. 同事说他的应用起不来了,因为我的代码里面多了一个空格!
  8. Django之Django debug toolbar调试工具
  9. Swift笔记(一):可选类型、语法基础
  10. C-Free注册码,密钥,到期解决办法
  11. [书籍分享]0-006.App营销解密:移动互联网时代的营销革命
  12. 《锋利的jQuery》二、jQuery的选择器
  13. pmp知识点(7)-项目成本管理
  14. 深海迷航坐标传送代码_深海迷航秘籍代码大全 美丽水世界秘籍代码教程
  15. Learning from class-imbalanced data: Review of methods and applications 论文阅读
  16. 360全景倒车影像怎么看_最近淘了一个360度全景倒车影像-4路行车记录仪监控录像,和大家分享一下...
  17. Redis连接报错【redis.clients.jedis.exceptions.JedisDataException: ERR Client sent AUTH, but no password 】
  18. H.266/VVC测试软件VTM
  19. VMware Workstation虚拟机装Win7详细高清图文教程
  20. 题目:A派生出子类B,B派生出子类C,并且在Java源代码中有如下声明,问以下哪个说法是正确的?()

热门文章

  1. 用筛法求之N内的素数
  2. linux+多个字符分割字符串数组中,String的split()方法可以将字符串按照特定的分隔符拆分成字符串数组...
  3. “数据结构与算法”被阿里大佬讲透了,这份笔记真是神了
  4. 无源元件和有源元件的区别-引用
  5. Big Data in Security – Part I: TRAC Tools
  6. npm、nrm两种方式查看源和切换镜像
  7. 2022企业oa办公系统有哪些品牌?常用oa办公软件系统哪个好?
  8. java优雅关闭io流
  9. 基于vue-cli搭建VUE.js项目
  10. 通用版路由器设置:华硕路由器设置图解