使用的环境:ubuntu16.04,qt5.4.0.
注:写了三天半完成的,使用的线程与进程知识,切歌,显示歌词,控制声量,发送弹幕,查找歌曲,切换桌面背景,模式选择等功能均已实现。但是还是初学者,必然有许多漏洞与不足,希望指正。

部分功能解析:
1.当前时间的获取

QTimer * timer = new QTimer;
timer ->start(1000);
connect(timer,&QTimer::timeout,[=](){//当1秒的时间结束,触发这个槽函数
QDateTime time = QDateTime::currentDateTime();//获取当前的时间
QString str = time.toString("yyyy-MM-dd \n hh:mm:ss");             });

2.mplayer的使用
volume * 1:设置音量的大小
mute 1/0 :设置音量的静音与取消(1为暂停,0为取消)
pause :暂停与继续
seek value :设置快退与快进,取决与value的正负值

  execlp("mplayer","myplayer","-idle","-slave","-quiet","-input","file=./a.txt","1.mp3",NULL);//这一个语句就是调用mplayer进程的命令//要尽量给其开辟一个新的进程或者是线程,因为其一旦运行,后面的代码就会被取代//最后面的哪一个NULL参数不能够被省略//每一个参数都有其的含义,可以看到前面两个参数都是mplayer,含义确实不一样地,第一个是可执行文件的名字,由他这个参数去查找命令,第二个参数是命令。

3.字符串的拼接
QString的使用与C++中的string并不是相同的,不能够通过+号来进行凭借(C++中能够直接+号拼接是因为这个+号被重载过了)
那么在qt中的QString怎么拼接呢

         //从lineEdit获得到ui上输入的字符,并把其存放在text中QString text = ui->lineEdit_saysomesthing->text();QDateTime time = QDateTime::currentDateTime();QString str = time.toString("yyyy-MM-dd  hh:mm:ss");              //获取当前的时间QString status = QString(" %1 %2").arg(text).arg(str);//字符串拼接

4.背景图的切换
我采用的是按钮,按钮按下,图片切换

   //按键改变桌面connect(ui->table_pushButton,&QPushButton::clicked,[=](){table_flag++;             // 图片的标志位if(table_flag % 3 == 1 )//给上图片的路径,这个pixmapPath是一个变量,定义在类中了,所以可以这么直接用上了{pixmapPath=(":/imag/photo_1.png");}else if(table_flag % 3 == 2){pixmapPath=(":/imag/photo_2.png");}//这个updata()是必须要有的,用来更新桌面的背景this->update();});

5.歌词的切割

//歌词解析
//传入歌曲的名字,得到与之对应的歌词地址
void Widget::Parsing_lyrics(QString)
{if(lrc.empty() == 0){lrc.clear();}char buff[32]="";//此时song_name[music_num]的类型是QString类型,需要转换为char * 类型,然后再进行其他的操作,此时获得到的是歌曲文件的地址//由于我这个地方偷懒了,把歌曲的名字都改为数字了,如果想要使用,就要自己再想想怎么把歌曲地址通过组包解包,变换为歌词的地址//在我这里是将./3.mp3---->./3.rlcstrcpy(buff,song_name[music_num].toUtf8().data()); //    ./*.mp3int n;sscanf(buff,"./%d.mp3",&n);printf("buff2: %d",n);char buff3[32]="";sprintf(buff3,"./%d.lrc",n);//       ./*.mp3  ------------------>  ./*.lrcprintf("%s\n",buff3);FILE * fp = fopen(buff3,"r");if(fp == NULL){perror("fopen");}char buff_lrc[128]="";while(fgets(buff_lrc,sizeof(buff_lrc),fp) != NULL){char *p = buff_lrc;if(p[1] >= '0' && p[1] <= '9'){char * q = p;while(*q == '['){if(q[10] == ']'){q += 11;}else{q+=10;}}while(*p == '['){int m = 0, n = 0;sscanf(p,"[%d:%d",&m,&n);this->lrc.insert(m*60+n,q);//printf("%d,%s\n",m*60+n,q);p+=10;}}}fclose(fp);}

6.自定义信号与槽
信号的来源选择使用emit发送,这个信号必须在类中定义哈,但是不用去实现
自定义的槽函数需要定义,并且实现

这是需要在.h中实现的
signals://这个信号也要自己写哦void change_progess(int value);//自定义的信号
private slots://自定义槽函数void changeProgess(int value);//自定义的槽函数
发出信号emit p->change_progess(rate_of_progress);//发出信号,外界接收,从而控制进度的显示
  //获得信号改变进度条      connect(this,SIGNAL(change_progess(int)),this,SLOT(changeProgess(int)));void Widget::changeProgess(int value)
{ui->progressBar->setValue(value);这个就是槽函数,改变页面上进度条
}

最后效果

代码如下
.cpp:

#include "widget.h"
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include "ui_widget.h"
#include <QMessageBox>
#include <QPainter>
#include <QPixmap>
#include <QDebug>
#include <algorithm>
#include <QTimer>
#include <QDateTime>
#include <time.h>void * father(void * arg);
void * father2(void * arg);
int gettime_flag;
int change_mode;   //改变模式标志位Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{//创建无名管道pipe(fd_pipe);//创建有名管道int ret2 = mkfifo("./a.txt",0666);if(0 == ret2){qDebug()<<"创建成功!\n"<<endl;}//创建子进程pid_t pid = fork();if(pid < 0){perror("fork");}else if(pid == 0){//子进程dup2(fd_pipe[1],1);execlp("mplayer","myplayer","-idle","-slave","-quiet","-input","file=./a.txt","1.mp3",NULL);}else{//父进程ui->setupUi(this);change_mode = 0;     //初始化模式为单曲播放模式music_num = 0;       //初始化播放曲目say_num = 0;         //初始化弹幕,从第0个开始进行滚动播放弹幕volume = 70;         //初始化音量volume_flat=1;       //静音标志位this->pixmapPath=":/imag/photo_1.png"; //初始化桌面get_song_name();     //调用该函数,获得所有的歌曲的名字get_say();           //调用该函数,获得弹幕的初始化table_flag=1;        //初始化桌面壁纸gettime_flag=0;      //全局变量,用于按下暂停后记录的标志位,按下暂停后,不再获取时间Parsing_lyrics(song_name[music_num]);//加载第一首歌的歌词,解析歌词,把歌词放入map容器中this->fd = open("a.txt",O_WRONLY);   //只写打开有名管道pthread_t pth3,pth4;pthread_create(&pth3,NULL,father,(void *)this);   //创建子线程pthread_detach(pth3);//线程分离pthread_create(&pth4,NULL,father2,(void *)this);pthread_detach(pth4);//暂停或者继续connect(ui->pause_pushButton,SIGNAL(clicked(bool)),this,SLOT(mystop(void)));//杀死子进程,再关闭父进程connect(ui->close_pushButton,SIGNAL(clicked(bool)),this,SLOT(myclose(void)));//加大声量connect(ui->volume_up_pushButton,SIGNAL(clicked(bool)),this,SLOT(turn_up_volume(void)));//减小声量connect(ui->volume_done_pushButton,SIGNAL(clicked(bool)),this,SLOT(reduce_the_volume(void)));//播放下一首connect(ui->next_pushButton,SIGNAL(clicked(bool)),this,SLOT(next_music(void)));//播放上一首connect(ui->before_pushButton,SIGNAL(clicked(bool)),this,SLOT(before_music(void)));//查找歌曲功能,lambal表达式connect(ui->find_pushButton,&QPushButton::clicked,[=](){//获得这一行输入的歌曲名QString text = ui->lineEdit->text();//qDebug()<<"get lintEdit:"<<text<<endl;QVector<QString>::iterator it = song_name.begin();QVector<QString>::iterator ret;//在容器中查找有没有这个歌曲的名字,使用迭代器查找ret = qFind(song_name.begin(),song_name.end(),text);if(ret != song_name.end()){QMessageBox::information(this,"yes","find it!");char buff[64]="";sprintf(buff,"loadfile %s\n",text.toUtf8().data());//如果找到了,进行组包之后,发送给有名管道,从而控制mplayer进行播放write(this->fd,buff,strlen(buff));//定义的函数,功能是传入指定的歌曲名字,然后进行歌词的解析,前提是你的文件目录下面得要有哈Parsing_lyrics(song_name[music_num]);}else{QMessageBox::information(this,"sorry","not find it!");}});//按键改变桌面connect(ui->table_pushButton,&QPushButton::clicked,[=](){table_flag++;if(table_flag % 12 == 1 )//给上图片的路径,这个pixmapPath是一个变量,定义在类中了,所以可以这么直接用上了{pixmapPath=(":/imag/photo_1.png");}else if(table_flag % 12 == 2){pixmapPath=(":/imag/photo_2.png");}else if(table_flag % 12 == 3){pixmapPath=(":/imag/photo_3.png");}else if(table_flag % 12 == 4){pixmapPath=(":/imag/photo_4.png");}else if(table_flag % 12 == 5){pixmapPath=(":/imag/photo_5.png");}else if(table_flag % 12 == 6){pixmapPath=(":/imag/photo_6.png");}else if(table_flag % 12 == 7){pixmapPath=(":/imag/photo_7.png");}else if(table_flag % 12 == 8){pixmapPath=(":/imag/photo_8.png");}else if(table_flag % 12 == 9){pixmapPath=(":/imag/photo_9.png");}else if(table_flag % 12 == 10){pixmapPath=(":/imag/photo_10.png");}else if(table_flag % 12 == 11){pixmapPath=(":/imag/photo_11.png");}//这个updata()是必须要有的,用来更新桌面的背景this->update();});//获得信号改变进度条connect(this,SIGNAL(change_progess(int)),this,SLOT(changeProgess(int)));//动态显示歌词connect(this,SIGNAL(lrc_time(int)),this,SLOT(show_lrc(int)));//用定时器获取当前时间并赋给label_timeQTimer *timer = new QTimer;timer->start(5000);//每五秒更换一条弹幕connect(timer,&QTimer::timeout,[=](){if(say_num == (say.size()-1)){say_num = 0;}else{say_num++;}//每隔五秒显示容器里面的内容ui->pushButton->setText(say[say_num]);});//获取从页面上输入的信息,并在后面加上当前的时间,并肩这个两条信息合并,插入到这个弹幕的容器中connect(ui->pushButton_say,&QPushButton::clicked,[=](){QString text = ui->lineEdit_saysomesthing->text();QDateTime time = QDateTime::currentDateTime();QString str = time.toString("hh:mm:ss");              //获取当前的时间QString status = QString(" %1 %2").arg(text).arg(str);//字符串拼接//将拼接的字符串放入容器中this->say.push_back(status);QMessageBox::information(this,"ok","insert suessful");//插入结束了之后,清空lineEditui->lineEdit_saysomesthing->clear();});}}//父线程用于向子线程发送消息(有名管道),来获得歌曲播放的时间,总时间,以及进度
void * father(void * arg)
{Widget * p = (Widget *)arg;while(1){if(gettime_flag % 2 == 0){//printf("father 1 now gettime_flag is :%d\n",gettime_flag);write(p->fd,"get_time_pos\n",strlen("get_time_pos\n"));usleep(100*100);write(p->fd,"get_time_length\n",strlen("get_time_length\n"));usleep(100*100);write(p->fd,"get_percent_pos\n",strlen("get_percent_pos\n"));usleep(100*1000);}else{//printf("stop 1\n");sleep(1);}}}//通过无名管道,获取歌曲的状态信息
void * father2(void * arg)
{Widget * p = (Widget *)arg;int time_now,time_all;while(1){//printf("father 2 now gettime_flag is :%d\n",gettime_flag);char buff[64]="";read(p->fd_pipe[0],buff,sizeof(buff));//printf("this is read son :%s",buff);if(strncmp(buff,"ANS_TIME_POSITION",strlen("ANS_TIME_POSITION")) == 0){//get timesscanf(buff,"ANS_TIME_POSITION=%d",&time_now);int minute = time_now / 60;int second = time_now % 60;char buf_time[32]="";sprintf(buf_time,"%02d:%02d",minute,second);p->ui->label_time->setText(buf_time);emit p->lrc_time(time_now);                   //发出信号,外界接收,从而控制歌词的显示}if(strncmp(buff,"ANS_LENGTH",strlen("ANS_LENGTH")) == 0){//get all timesscanf(buff,"ANS_LENGTH=%d",&time_all);int minute2 = time_all / 60;int second2= time_all % 60;char buf_time2[32]="";sprintf(buf_time2,"%02d:%02d",minute2,second2);p->ui->label_time_all->setText(buf_time2);//printf("all time is : %d\n",time_all);}if(strncmp(buff,"ANS_PERCENT_POSITION",strlen("ANS_PERCENT_POSITION")) == 0){int rate_of_progress;sscanf(buff,"ANS_PERCENT_POSITION=%d",&rate_of_progress);//printf("get rate of progress is %d\n",rate_of_progress);emit p->change_progess(rate_of_progress);//发出信号,外界接收,从而控制进度的显示}}
}Widget::~Widget()
{delete ui;
}
//歌词解析
void Widget::Parsing_lyrics(QString)
{if(lrc.empty() == 0){lrc.clear();}char buff[32]="";strcpy(buff,song_name[music_num].toUtf8().data()); //    ./*.mp3int n;sscanf(buff,"./%d.mp3",&n);printf("buff2: %d",n);char buff3[32]="";sprintf(buff3,"./%d.lrc",n);//       ./*.mp3  ------------------>  ./*.lrcprintf("%s\n",buff3);FILE * fp = fopen(buff3,"r");if(fp == NULL){perror("fopen");}char buff_lrc[128]="";while(fgets(buff_lrc,sizeof(buff_lrc),fp) != NULL){char *p = buff_lrc;if(p[1] >= '0' && p[1] <= '9'){char * q = p;while(*q == '['){if(q[10] == ']'){q += 11;}else{q+=10;}}while(*p == '['){int m = 0, n = 0;sscanf(p,"[%d:%d",&m,&n);this->lrc.insert(m*60+n,q);//printf("%d,%s\n",m*60+n,q);p+=10;}}}fclose(fp);}//静态插入所有的歌曲的位置
void Widget::get_song_name(void)
{this->song_name.push_back("./1.mp3");this->song_name.push_back("./2.mp3");this->song_name.push_back("./3.mp3");this->song_name.push_back("./4.mp3");this->song_name.push_back("./5.mp3");this->song_name.push_back("./6.mp3");this->song_name.push_back("./7.mp3");this->song_name.push_back("./8.mp3");this->song_name.push_back("./9.mp3");this->song_name.push_back("./10.mp3");this->song_name.push_back("./11.mp3");this->song_name.push_back("./12.mp3");this->song_name.push_back("./13.mp3");}
//静态插入弹幕的消息
void Widget::get_say()
{this->say.push_back("虽然只能输入英文");this->say.push_back("有弹幕发就好");this->say.push_back("虽然是滚动的");this->say.push_back("但是,暂且就当这是一个功能吧");this->say.push_back("将就着用吧");this->say.push_back("周继是一个大帅逼!");this->say.push_back("周继是一个大帅逼!!");this->say.push_back("周继是一个大帅逼!!!");this->say.push_back("周继是一个大帅逼!!!!");
}void Widget::paintEvent(QPaintEvent *ev)
{//绘制背景图//定义一个画家QPainterQPainter *p = new QPainter(this);//在主窗口上画图//定义图片对象QPixmap pix;//pix加载一张图片pix.load(this->pixmapPath);//修改图片大小pix.scaled(this->width(), this->height());//画家花背景图p->drawPixmap(0,0,this->width(), this->height(), pix);
}void Widget::mystop(void)
{//暂停或者播放write(this->fd,"pause\n",strlen("pause\n"));gettime_flag++;//printf("pause now gettime_flag is :%d\n",gettime_flag);//printf("写入管道字节数:%ld\n",write_num);
}
//杀死子进程,然后关闭父进程
void Widget::myclose(void)
{//kill sonkill(0,9);this->close();
}
//加声量
void Widget::turn_up_volume(void)
{if(this->volume >= 100){//printf("sorry,The current volume is at maximum\n");qDebug()<<"sorry,The current volume is at maximum"<<endl;QMessageBox::information(this,"sorry","This is the maximum volume!");}else{this->volume +=5;//int fd = open("a.txt",O_WRONLY);char buff[64]="";sprintf(buff,"volume %d 1\n",this->volume);write(this->fd,buff,strlen(buff));}
}
//减声量
void Widget::reduce_the_volume(void)
{if(this->volume <= 0){printf("sorry,The current sound volume is at a minimum\n");QMessageBox::information(this,"sorry","This is the minimum volume!");}else{this->volume -= 5;//int fd = open("a.txt",O_WRONLY);char buff[64]="";sprintf(buff,"volume %d 1\n",this->volume);ssize_t write_num = write(this->fd,buff,strlen(buff));printf("写入管道:%s\n",buff);}
}
//下一曲
void Widget::next_music(void)
{if(music_num == song_name.size()-1){printf("All the songs have been played\n");QMessageBox::information(this,"sorry","this is lost one!");}else{music_num++;Parsing_lyrics(song_name[music_num]);//int fd = open("a.txt",O_WRONLY);char buff[64]="";printf("now song is :%s\n",song_name[music_num].toUtf8().data());sprintf(buff,"loadfile %s\n",song_name[music_num].toUtf8().data());write(this->fd,buff,strlen(buff));}}
//上一曲
void Widget::before_music(void)
{if(music_num == 0){printf("You can't go any further because this is the last song\n");QMessageBox::information(this,"sorry","this is lost one!");}else{music_num--;Parsing_lyrics(song_name[music_num]);//int fd = open("a.txt",O_WRONLY);char buff[64]="";printf("now song is :%s\n",song_name[music_num].toUtf8().data());sprintf(buff,"loadfile %s\n",song_name[music_num].toUtf8().data());write(this->fd,buff,strlen(buff));}}
//根据获取时间信号来的动态控制歌词展示
void Widget::show_lrc(int values)
{QFont ft;ft.setPointSize(12);ui->label_lrc_one->setFont(ft);ui->label_lrc_two->setFont(ft);QMap<int,QString>::iterator it = lrc.begin();for(;it != lrc.end();it++){if(it.key() == values){ui->label_lrc_one->setText(lrc[values]);if(lrc.upperBound(values).key() != lrc.end().key()){ui->label_lrc_two->setText(lrc.upperBound(values).value());}}}
}
//静音按钮(这个是转到槽,没有用connect进行连接)
void Widget::on_novolume_pushButton_clicked()
{if(this->volume_flat % 2 == 1){write(this->fd,"mute 1\n",strlen("mute 1\n"));}else if(this->volume_flat % 2== 0){write(this->fd,"mute 0\n",strlen("mute 0\n"));}this->volume_flat++;
}
//更改进度条的槽函数
void Widget::changeProgess(int value)
{//响应进度到100时,切换歌曲,且只能切换一次//设置随机数种子srand(time(NULL));ui->progressBar->setValue(value);if(100 == value ){if(0 == change_mode){printf("单曲播放模式,歌曲结束,等待切换下一首\n");}if(1 == change_mode){printf("单曲循环模式\n");char buff[64]="";sprintf(buff,"loadfile %s\n",song_name[music_num].toUtf8().data());write(this->fd,buff,strlen(buff));}if(2 == change_mode){printf("顺序播放模式\n");music_num++;Parsing_lyrics(song_name[music_num]);char buff[64]="";printf("now song is :%s\n",song_name[music_num].toUtf8().data());sprintf(buff,"loadfile %s\n",song_name[music_num].toUtf8().data());write(this->fd,buff,strlen(buff));}if(3 == change_mode){printf("随机播放模式\n");music_num = rand()%13+1;Parsing_lyrics(song_name[music_num]);char buff[64]="";printf("now song is :%s\n",song_name[music_num].toUtf8().data());sprintf(buff,"loadfile %s\n",song_name[music_num].toUtf8().data());write(this->fd,buff,strlen(buff));}usleep(500 * 1000);      //防止一直切换,100这个值会接受到多次}
}void Widget::on_comboBox_currentIndexChanged(int index)
{if(0 == index){printf("单曲播放模式\n");}if(1 == index){printf("单曲循环模式\n");}if(2 == index){printf("顺序播放模式\n");}if(3 == index){printf("随机播放模式\n");}change_mode = index;
}

.h:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <vector>
#include <QString>
#include <QPaintEvent>
#include <QMap>
namespace Ui {class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();int volume;                    //音量QVector<QString> song_name;    //存放所有的歌曲的名字// say somethingQVector<QString> say;          //存放弹幕的容器//lrcQMap<int,QString> lrc;         //存放歌词的容器void Parsing_lyrics(QString);  //歌词解析int music_num;int say_num;void get_song_name(void);void get_say(void);int fd;int volume_flat;void paintEvent(QPaintEvent *ev);//重写画家事件int fd_pipe[2];QString pixmapPath;int flag;int table_flag;Ui::Widget *ui;
public slots:void mystop(void);void myclose(void);void turn_up_volume(void);void reduce_the_volume(void);void next_music(void);void before_music(void);//歌词显示void show_lrc(int values);
private slots:void on_novolume_pushButton_clicked();void changeProgess(int value);void on_comboBox_currentIndexChanged(int index);signals:void change_progess(int value);void lrc_time(int value);
private:};#endif // WIDGET_H

界面文件

qt实现MP3的歌曲切换,歌词、进度、模式选择等实现(附源码)相关推荐

  1. 基于QT开发的音乐播放器(附源码)

    基于QT开发的音乐播放器(附源码) 一.简介 1.介绍 2.功能描述 3.系统功能层次模块图 4.各模块功能描述 (1)播放界面 (2)歌词 (3)歌曲信息 (4)歌曲列表 5.文件格式 6.运行环境 ...

  2. 【QT/C++】基于QT开发的一款A-SOUL元素的视频播放器(附源码)

    [QT/C++]基于QT开发的一款关于A-SOUL的视频播放器(附源码) 前言 一.软件使用说明 1.运行软件的界面如下 2.操作软件的步骤 二.软件设计说明 1.UI界面的设计 2.主代码中的部分函 ...

  3. (附源码)计算机毕业设计SSM基于的在线怀旧电影歌曲听歌系统

    (附源码)计算机毕业设计SSM基于的在线怀旧电影歌曲听歌系统 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclisp ...

  4. html怎么控制进度条,HTML如何实现进度条?附源码

    进度条在网页开发中还是很常见的,比如当我们下载某个文件时,会显示下载进度.那么这篇文章 w3cschool 小编来教你 HTML 如何实现进度条. progress 标签 在 HTML5 中,有专门的 ...

  5. java幻灯片效果_Java实现多种幻灯片切换特效(附源码)

    Java实现多种幻灯片切换特效(附源码)以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 功能说明 代码实现了多种幻灯片变 ...

  6. OsgEarth —— 笔记2 - Qt窗口加载earth地球(附源码)

    效果         相关文章      OSG -- 笔记1 - 指令调用模型      OSG -- 笔记2 - 加载模型(附源码)      OSG -- 笔记3 - 绘制矩形(附源码)     ...

  7. Qt数据库练习之QSqlTableModel的使用(MySql数据库示例,含源码+注释)

    文章目录 一.操作示例 1.1 修改记录(数据) 1.2 添加记录(数据) 1.3 删除记录(数据) 1.4 取消操作 1.5 排序操作 1.6 查询操作 二.了解QSqlTableModel 三.源 ...

  8. QT界面免费版开源图片转文字工具程序完整版附源码

    QT界面免费版开源图片转文字工具程序完整版附源码 需求源码的朋友请留言 操作步骤如下:

  9. 原创:Android应用开发记录-Andorid歌词秀(4)完成,含源码

    最新版软件请参照: Android应用开发记录-字幕播放器(5)完善 功能简介: 1.自动读取与音乐相同位置的歌词文件 2.根据播放进度,表示当前的歌词 3.按歌词语句快进,快退. 可以用来记歌词,学 ...

最新文章

  1. 区块链基础--工作量证明
  2. 用Latex写IEEE论文
  3. [OJ] Wildcard Matching (Hard)
  4. 【.NET框架】—— ASP.NET MVC5路由基础(五)
  5. 【白皮书下载】开源生态白皮书(2020年).pdf(附下载链接)
  6. 难过的时候看一看 再坏能有多坏!
  7. 可以进行单元测试么_大量实例助攻,让你的单元测试更高效
  8. java项目打成war包,使用ide打包部署在tomcat中
  9. java导出word文档(office,wps均可)
  10. 【LeetCode】460 and 1132(LFU缓存机制)
  11. c语言大作业成绩分析问题,河南科技大学c语言课程设计-综合排序设计报告-成绩分析问题.doc...
  12. [下属谈话]管理者与下属谈话的技巧以及注意点
  13. 用jar包生成maven依赖
  14. 吴秀波事件女主,被耽误的高阶玩家,一年12个月烧钱游遍全世界
  15. 学编程脚本 android,Auto.js安卓免root脚本开发教程
  16. DELL设备维保查询方法
  17. 文件上传漏洞 — 前端JS绕过、MIME类型绕过
  18. 华云大咖说 | 业务转型中的IT云化服务——安超云基座方案介绍
  19. 华为OD机试题 - 新员工座位安排系统(JavaScript)| 机考必刷
  20. 异步社区两周年记-好礼不断

热门文章

  1. 最常见的六种跨域解决方案
  2. 【Unity】Shader之旗帜漂浮效果
  3. 图论-网络流⑦-费用流解题
  4. python web开发框架比较
  5. 数据结构学习——图书管理系统
  6. 04-android-ip定位
  7. 洛谷4147 玉蟾宫
  8. 防护CC攻击的手段有哪些?
  9. 连接ORACLE数据库提示:ORA-12541: TNS: 无监听程序
  10. 计算机网络面试常考题目汇总