学习内容:Scala,Linux,Shell脚本,制作双绞线及服务器重置
10月7日黑马Linux
学习内容:
虚拟机快照,Linux命令基本格式,ls命令,cd切换工作目录,pwd查看当前工作目录,相对路径和绝对路径,特殊路径符,mkdir命令,touch创建文件,cat命令查看文件内容,cat命令查看文件内容
摘要
虚拟机快照
添加快照
在VMware中右击Centos7选择快照—->快照管理器—–>拍摄快照
还原快照
在快照管理器中找到要还原的快照点击后—–>再点击转到
Linux命令基本格式
通用格式:
command [-options] [parameter]
-
command:命令本身
-
options: [可选,非必填] 命令的一些选项,可以通过选项控制命令的行为细节
-
parameter: [可选,非必填] 命令的参数,多数用于命令的指向目标等
注意: 语法中[],表示可选的意思.
eg.
ls -l /home/test
ls是命令本身, -l是选项,/home/test是参数
意思是以列表的形式,显示/home/test 目录内的内容.
特殊路径符
. 表示当前目录,比如 cd ./Desktop 表示切换到当前目录下的Desktop目录内,和cd Desktop标果一样
.. 表示上一级目录,比如: cd .. 即可切换到上一级目录,cd ../.. 切换到上两级的目录
~ 表示HOME目录,比如 cd ~ 即可切换到HOME目录
mkdir命令
通过mkdir命令可以创建新的目录
语法:
mkdir [-p] Linux路径
-
参数必填,表示Linux路径,即要创建的文件夹的路径,相对路径或绝对路径均可
-
-p 选项可选,表示自动创建不存在的父目录,适用于创建连续多层级的目录
cat命令 查看文件内容
可以通过cat 查看内容
语法:
cat Linux路径
cat同样是没有选项,只有必填参数,参数表示:被查看的文件路径,相对,绝对,特殊路径符均可以使用.
more支持翻页,如果文件内容过多,可以一页页的展示
语法:
more linux路径
同样是没有选项,只有必填参数,参数表示:被查看的文件路径,相对,绝对,特殊路径符均可以使用.
注意: 按Q可以退出
遇到的问题
无
总结
今天学习的Linux虚拟机的安装的配置,然后学了一些基本的linux命令,比如像ls显示当前目录下的文件及文件夹,创建文件或者文件夹,还有对文件查看内容.最近有点感冒,加上今天主要是弄了一下服务器,还有刚来学校的缘故,感觉状态不是很好,最近需要调整一下状态.
10月9日 黑马Scala
学习内容:
cp-mv-rm,which-find,grep-wc-管道符,echo-tail-重定向符,vi编辑器,用户及文件权限控制
视频链接:第二章-09-cp-mv-rm-命令哔哩哔哩bilibili
摘要
一.文件操作命令(cp.mv,rm)
1.cp命令复制文件文件夹
cp命令:用于复制文件/文件夹,
语法:
cp [-r] 参数1 参数2
-
-r 选项,可选,用于复制文件夹使用,表示递归
-
参数1,Linux路径,表示被复制的文件或文件夹
-
参数2,Linux路径,表示要复制去的位置.
2.mv移动文件或文件夹
mv命令用于移动文件/文件夹
语法:
mv 参数1 参数2
-
参数1: Linux路径,表示被移动的文件或文件夹
-
参数2: Linux路径,表示要移动去的地方,如果目标不存在,则进行改名,确保目标存在
还可以用于重命名
mv test2.txt test3.txt
3.rm删除文件,文件夹
rm命令用于删除文件,文件夹
语法:
rm [-r -f] 参数1 参数2 …… 参数N
同cp命令一样,-r选项用于删除文件夹
-f 表示force,强制删除(不会弹出提示确认信息)
-
普通用户删除内容不会弹出提示,只有root管理员用户删除内容会有提示
参数1,参数2, …… ,参数N 表示要删除的文件或文件夹路径,按照空格隔开
rm命令支持通配符*,用来做模糊匹配
符号* 表示通配符,即匹配任意内容(包括空)
-
可以通过su -root,并输入密码切换到root用户
-
通过exit命令,退回普通用户
二.查找命令
1.which命令
which,用于查找所使用的一系列命令的程序文件存放在哪里.
语法:
which 要查找的命令
2.find命令
按照文件名查找文件
find用于查找搜索指定的文件,相当于window中搜索文件.
语法:
find 起始路径 -name “被查找文件名”
同样在find命令中也可以使用通配符进行查找*
三.grep,wc和管道符
1.grep命令
grep:从文件中通过关键字过滤文件行
语法:
grep [-n] 关键字 文件路径
-
选项-n,可选,表示在结果中显示匹配的行的行号.
-
参数,关键字,必填,表示过滤的关键字,带有空格或其他特殊符号,建议使用“ ” 将关键字包围起来
-
参数, 文件路径,必填, 表示要过滤内容的文件路径,可以作为内容输入端口
2.wc命令
可以通过wc命令统计文件的行数,单词数量等
语法:
wc [-c -m -] -w] 文件路径
-
选项, -c , 统计bytes数量,count
-
选项, -m, 统计字符数量,number
-
选项, -l , 统计行数,line
-
选项, -w, 统计单词数量,word
-
参数,文件路径,被统计的文件,可作为内容输入端口
3.管道符
管道符: |
含义是: 将管道符左边命令的结果,作为右边命令的输入
还可以使用多个管道符进行使用.
四.echo,tail和重定向符
1.echo命令
可以使用echo命令在命令行内输出指定内容.
语法:
echo 输出的内容
无需选项,只有一个参数,表示要输出的内容,复杂内容可以用“ ”包围
如果带有空格或\等特殊符号,建议使用双引号包围,因为不包围,空格后很容易被识别为参数2,尽管echo不受影响.
(1)反引号`
比如我们想要使用echo输入当前的工作目录,直接打echo pwd他只会识别成普通字符输出.
所以我们需要使用反引号``将其包围,被包围后会作为指令被执行.
echo `pwd`
2.重定向符
重定向符: > 和 >>
> ,将左侧命令结果,覆盖写入到符号右侧指定的文件中
>> ,将左侧命令结果,追加写入到符号右侧指定的文件中
eg.
echo "hello linux" > test.txt
3.tail
用来查看文件尾部内容,跟踪文件的最新更新,语法如下:
语法:tail [-f -num] 参数
-
参数:Linux路径,表示被跟踪的文件路径
-
选项:-f,表示持续跟踪
选项-num, 表示,查看尾部多少行,不写默认10行
五.Linux用户和权限
普通用户的权限,一般在其HOME目录内是不受限的
一旦出了HOME目录,大多数地方,普通用户仅有只读和执行权限,无修改权限.
5.修改权限控制-chmod
chmod命令,修改文件,文件夹的权限信息.
注意: 只有文件,文件夹的所属用户或root用户可以修改.
语法 : chmod [-R] 权限 文件或文件夹
选项:-R,对文件夹内的全部内容应用同样的操作.
还可以使用数字r=4,w=2,x=1
6.修改权限控制-chown
语法: chown [-R] [用户] [:] [用户组] 文件或文件夹
选项:-R ,同chmod,对文件夹内全部内容应用相同规则
选项: 用户,修改所属用户
选项: 用户组, 修改所属用户组
: 用户分隔用户和用户组
遇到的问题
无
总结
今天学习的内容有对文件操作主要是对文件的复制移动和删除,这一部分的内容在之前有学习过一些,然后是查找命令,使用find,像Windows系统中搜索栏一样,还学习了多种的符号,管道符,反引号等,还学会了使用vim编辑器,但是对vim编辑器的使用还不是很熟练,有很多的快捷键都不是很清楚,希望在后面多使用中,逐渐熟练,最后就是对Linux中用户权限进行创建用户和对用户信息进行修改.今天感觉学习状态还可以,逐渐进入状态了.
10月10日 黑马Linux
学习内容:
systemctl控制软件启动关闭,软链接,日期和时区,配置Linux固定IP地址,网络请求和下载
摘要
systemctl命令
Linux系统很多软件均支持使用systemctl命令控制:启动,停止,开机自启.
语法: systemctl start |stop |status | enable | disable 服务名
-
start 启动
-
stop 关闭
-
status 查看状态
-
enable 开启开机自启
-
disable 关闭开机自启
软连接
ln命令创建软连接
在系统中创建软连接,可以将文件,文件夹链接到其他位置.
这个地方跟windows中的快捷方式很像.
语法: ln -s 参数1 参数2
-s 选项,创建软连接
参数1: 被链接的文件或文件夹
参数2: 要链接去的目的地
日期,时区
1.date命令
date命令是在命令行中查看系统的时间
语法: date [-d] [+格式化字符串]
-d ,按照给定的字符串显示日期,一般用于日期计算
格式化字符串: 通过特定的字符串标记, 来控制显示的日期格式
%Y 年
%y 年份后两位数字
%M 月份
%d 日
%H 小时
%M 分钟
%S 秒
%s 时间戳
2.修改时区
系统默认的时区是UTC并不是中国的东八区
需要使用root权限将,时区修改成东八区时区
扩展:
1.这里还可以使用cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2.tzselect——> 选择Asia 5 —->China 9 —–>yes 1 ——-> TZ=‘Asia/Shanghai’; export TZ
3.ntp程序
我们可以通过ntp程序自动校准系统时间
启动并设置开机自启:
systemctl start ntpd
systemctl enable ntpd
当ntpd启动后会定期帮我们联网校准系统时间.
还可以手动校准(需root) : ntpdate -u ntp.aliyun.com
IP地址和主机名
1.Linux中修改主机名
可以使用命令: hostname
查看主机名
可以使用指令: hostnamectl set-hostname 主机名
修改主机名(需root)
重新登录FinalShell就可以看到主机名已修改
2.在VMware 中配置固定IP
配置固定IP需要两步:
1.在VMware中配置IP地址网关和网段
2.在Linux系统中手动修改配置文件(在/etc/sysconfig/network-scripts/ifcfg-ens33),固定IP
3.执行systemctl restart network
重启网卡
端口
1.查看端口占用
可以通过Linux命令去查看端口的占用情况
使用nmap命令,安装nmap
语法: nmap 被查看的IP地址
可以通过netstat
命令,查看指定端口的占用情况
语法: netstat -anp | grep 端口号
, 安装netstat
遇到的问题
修改时区无效
修改了时区但是没有用,没有变成东八区的CST
然后在直接再虚拟机的Centos上直接进行设置,发现已经是东八区,然后使用虚拟机中Centos的终端date命令查看发现已经是东八区,但是在xshell连接中使用date命令发现还是一样的,重新链接后发现就改了.
虽然闹了个乌龙,但是不仅学会了多种修改成东八区的方法,也发现xshell连接上的Centos与虚拟机是没有同步的.所以以后某些操作还是要重新连接一下.
总结
今天学习的内容感觉让对Linux系统的使用更加的熟练,学会使用很多快捷键,也可以使用指令去下载软件和发送网络请求,也解决了之前使用ssh连接服务器然后,Linux系统的IP因为DHCP自动分配而导致的ip更换而需要重新更改的情况,在问题中也知道了不能太依靠ssh,ssh没有跟虚拟机同步,也需要在真机上进行操作.今天早上弄了一下台式机耽搁了一点时间,但是晚上的时候,感觉学习状态很好.希望之后能继续保持.
10月11日 黑马Linux
学习内容:
进程管理,主机状态监控,环境变量,Linux文件的上传和下载,压缩和解压,MySQL软件安装,Tomcat软件安装部署
视频链接: 第四章-10-进程管理哔哩哔哩bilibili
摘要
进程
1.查看进程
可以通过ps命令查看Linux系统中的进程信息
语法: ps [-e -f]
选项:-e ,显示出全部的进程
选项: -f,以完全格式化的形式展示信息(展示全部信息)
2.关闭进程
在Linux中,可以通过kill命令关闭进程
语法: kill [-9] 进程ID
选项: -9 ,表示强制关闭进程,不使用此选项会向进程发送信号要求关闭,但是否关闭还是要看进程本身
主机状态监控
1.查看系统资源占用
可以通过top命令查看CPU,内存使用情况,类似Windows的任务管理器
语法: top
磁盘信息监控
使用df命令,可以查看硬盘的使用情况
语法: df [-h]
选项: -h ,以更加人性化的单位显示
主机状态监控
1.自行设置环境变量
Linux环境变量可以用户自行设置:
-
临时设置,语法:
export 变量名=变量值
-
永久生效
-
针对当前用户生效,配置在当前用户的:
~/bashrc
文件中 -
针对所有用户生效,配置在系统的:
/etc/profile
文件中 -
并通过语法: Source配置文件,进行立刻生效,或重新登录FinalShell 生效
-
压缩和解压缩
1.tar命令
使用tar进行压缩和解压缩的操作
语法: tar [-c -v -x -f -z -C] 参数1 参数2 ... 参数N
-
-c: 创建压缩文件,用于压缩模式
-
-v: 显示压缩,解压过程,用于查看进度
-
-x,解压模式
-
-f,要创建的文件,或要解压的文件,-f选项必须在所有选项中位置处于最后一个
-
-z ,gzip模式,不使用 -z 就是普通的tarball格式
-
-C: 选择解压的目的,用于解压模式
2.zip命令压缩文件
可以使用zip命令,压缩文件为zip压缩包
语法: zip [-r] 参数1 参数2 ... 参数N
-
-r : 被压缩的包含文件夹的时候,需要使用-r 选项,和rm.cp等命令的-r效果一致.
3.unzip命令解压文件
使用unzip命令,可以方便的解压zip压缩包
语法: unzip [-d] 参数
-
-d : 指定要解压去的位置,同tar 的-C选项
-
参数,被解压的zip压缩包文件
遇到的问题
下载tomcat的时候出现访问不了对应的网站出现404的情况,
使用tomcat已经启动但是使用浏览器访问lcoalhost:8080的时候是访问不了的
然后重新配置了一下java的配置后面导致基本命令都失效了
最后将java直接卸载了,然后使用apt进行自动的安装,最后就可以启动了.
总结
今天学习开始的时候学习如何查询和关闭进程,然后查询资源的占用情况,最后学会使用tar命令进行压缩和解压缩,后面学习下载和配置java和下载tomcat的时候出现了挺多的问题,后面都导致一些基本的命令都打不出来,最后逐渐修复,也配好了环境,最后java用apt下载的方式自动配置环境变量,中间出现了一个问题就是tomcat已经显示启动了但是访问网页的时候无法访问.
10月12日 黑马Linux
学习内容:
Nginx安装部署,RabbitMQ安装部署,Redis安装部署,Elasticsearch安装部署
摘要
Ubuntu启用SSH,通过局域网登录Ubuntu机器
这里是因为感觉两台电脑操作起来换来换去有点麻烦,所以想使用ssh进行远程连接操作.
1.打开终端,并且安装openssh-server软件包:
sudo apt update sudo apt install openssh-server
当被提示时,输入你的密码并且按 Enter,继续安装。
02.一旦安装完成之后,SSH 服务将会被自动启动。你可以验证 SSH 是否正在运行,输入:
sudo systemctl status ssh
输出将会告诉你服务正在运行,并且启用开机启动。
03.Ubuntu 自带一个配置防火墙配置工具,称为 UFW。如果防火墙在你的系统上被启用,请确保打开了 SSH 端口:
sudo ufw allow ssh
04.使用ifconfig 查看ip地址
sudo ifconfig
05.Ubuntu中允许root用户远程登录
编辑配置文件:
sudo vim /etc/ssh/sshd_config
取消注释并将PermitRootLogin prohibit-password更改为:PermitRootLogin yes
06.重启ssh服务
sudo systemctl restart sshd
问题
FinalShell root文件夹打开不了
1.切换ROOT用户:
su -
2.再输入命令:
chmod 777 /root
这里是因为权限不足而导致,所以需要使用chmod进行修改权限.
Linux下安装jdk1.8查看版本的时候报出:
*-bash: /usr/local/jdk1.8.0_144/bin/java: /lib/ld-linux.so.2: bad ELF interpreter: 没有那个文件或目录*
使用命令
sudo yum install glibc.i686
再次使用java -version 就显示JDK版本.
Ubuntu重设密码
因为下午重装了Ubuntu系统,但是切换成root用户的时候一直出现密码错误的情况.
1.启动或者重启Ubuntu长按shift进入grub菜单;
选择第二个高级选项,按住e进入
按F10,选择recovery mode进入Recovery Menu界面
选择root Drop to root shell prompt*
修改root密码操作:
输入 passwd 输入新密码:# 再输入一遍密码:#
4.按Ctrl+Alt+Del重启系统。
扩展学习
Ubuntu允许root远程登陆方法_permitrootlogin prohibit-password-CSDN博客
ssh远程连接Ubuntu 20.04_ssh ubuntu_y22y22y的博客-CSDN博客
如何在 Ubuntu 20.04 上安装 Nginx - 知乎 (zhihu.com)
Ubuntu RabbitMq 安装与运行(安装篇)nurumq绿竹痕的博客-CSDN博客
-bash: /usr/local/jdk1.8.0_144/bin/java: /lib/ld-linux.so.2: bad ELF interpreter: 没有那个文件或目录-CSDN博客
【超详细含图】Ubuntu系统忘记root密码的解决方法_ubuntu忘记root密码-CSDN博客
如何安装 Ubuntu 22.04 LTS 桌面版 (图文教程) ? - 知乎 (zhihu.com)
联想台式机安装Ubuntu 20.04 LTS_联想台式机安装ubuntu系统-CSDN博客
总结
今天遇到了好多问题,一直在装软件,跟着黑马装软件,黑马没有一个是可以的,所以都要上csdn查询资料,而且一直会出现错误,频繁的出现错误,感觉有点很难受,但是已经安装过的软件,再一次安装也会更加熟练,今天也把台式机进行了重装,重装成ubuntu的新版本,虽然中间也遇到了不少的问题,但是最终还是重装好了,还是挺有成就感的,希望下星期回来能把后面的软件安装好.
10月16日 黑马Scala
学习内容:
集群化软件安装前置准备,scp命令,Zookeeper安装部署,Kafka集群部署
视频链接: 第五章-11-集群化软件安装前置准备哔哩哔哩bilibili
问题
我使用yum的时候有时候就会出现这种情况
解决方法:
删除yum.repos.d目录下所有文件
rm -f /etc/yum.repos.d/*
然后重新下载阿里的
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
清理缓存
yum clean all
然后就可以正常的使用yum安装了
root权限下修改文件权限遇到 chmod: changing permissions of '***': Operation not permitted
配置了ssh免密登录后,还是一样需要使用密码,查了好多的文档也没有结果.最后我决定直接进行重装,重新配置了一个centos7,然后配置集群,最后就可以使用免密登录了.
总结
今天主要是弄ssh免密登录弄了一天,一直需要密码,不知道是什么原因,用了好多文档的方法也没有效果,最后以为是root用户不行,但是有一个同学可以使用ssh免密登录,所以最后决定直接进行重装,最后重新配置了一遍老师的免密登录就可以直接进行登录了.感觉今天在这个ssh免密登录上花费了大量的时间,主要是ssh免密登录挺重要的所以想弄出来,所以后面需要赶一下进度了.
10月17日 黑马Linux
学习内容:
Hadoop集群部署,HBASE集群部署,Spark分布式内存计算集群部署,Flink分布式内存计算集群部署
视频链接: [第五章-15-Hadoop集群部署集群化软件]哔哩哔哩bilibili
摘要
scp
scp [-r] 参数1 参数2
-
-r选项用于复制文件夹使用,如果复制文件夹,必须使用-r
-
参数1:本机路径 或 远程目标路径
-
参数2:远程目标路径 或 本机路径
遇到的问题
格式化hadoop出现报错
Hadoop集群搭建格式化出现错误_error conf.configuration: error parsing conf hdfs--CSDN博客
发现是因为配置文件有错误.然后我重新去看配置文件.
发现每个配置文件粘贴的时候总是前面一段的内容没了
是因为没有进入vim的插入模式,需要先按i进行插入模式再进行粘贴.
改完之后hadoop就能正常格式化了
缺少datanode进程
此时启动hadoop,但是比老师少了一个datanode进程
Hadoop启动集群子节点没有DataNode节点解决方法-CSDN博客
然后我将/tmp/dfs文件夹直接进行删除然后执行,hdfs namenode -format然后就没问题了
最后重新启动hadoop就有datanode进程了.
kafka一直出现拒绝连接的情况
一开始我以为配置错误了,所以重新配置了两遍,最后发现需要启动zookeeper才能启动kafka
总结
今天还是配置文件,但是总是遇到问题,开始是hadoop格式化出现问题,然后发现是因为每次进入vim进行粘贴配置的时候都少了一段,最后启动后但是datanode进程是没有的所以,删除了data文件夹,重新格式化,就解决了.感觉总是出现一些问题,有时候被迫只能重新的使用快照进行还原.
10月18日 尚硅谷Shell
学习内容:
变量,条件判断流程控制,控制台输入,系统函数.
视频链接: 066扩展篇Shell编程(一)Shell概述哔哩哔哩_bilibili
摘要
特殊变量
1.$n
$n :(功能描述:n 为数字,0 代表该脚本名称,1-9 代表第一到第九个参数,十以 上的参数,十以上的参数需要用大括号包含,如${10}
2.$*、$@
1)基本语法 $* (功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体) $@ (功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待
遇到的问题
Hadoop的位数问题与Java不匹配
只需要在hadoop-env.sh和yarn-env.sh中添加如下语句就行:
export HADOOP_COMMON_LIB_NATIVE_DIR=${HADOOP_PREFIX}/lib/native export HADOOP_OPTS="-Djava.library.path=$HADOOP_PREFIX/lib"
编写.sh read的时候初夏了语法错误,但是打开代码写的是正确的.
最后这里发现使用了中文的引号,因为前面是黄色的双引号,后面却是红色的.
总结
今天开始学习Shell,Shell的话,一开始在老师讲bash模式,进入子Shell和父Shell的时候,还是有点模糊,但是多听了两遍之后就理解了,父Shell包含了子Shell,父Shell中的变量改了,子Shell也会随着改变,但是子Shell改了,父Shell不会改变.像一些流程控制或者是循环的话还是比较好理解的跟Java那些语言差不多,只不过是有一些语法的不同,有一点比较难受的是,在书写Shell的时候等号两边不能使用空格隔开否则会出现语法错误的情况,还有就是在进行赋值的时候要在参数前面加上$符号,来代指前面的参数.总之今天的学习内容对于我来说还是比较容易的.
10月19日 黑马Linux
学习内容:
自定义函数,正则表达式,awk,cut,Scala环境搭建
视频链接:
081扩展篇Shell编程(七)函数(二)自定义函数哔哩哔哩bilibili
尚硅谷大数据技术之Scala入门到精通教程(小白快速上手scala)哔哩哔哩bilibili
摘要
自定义函数
这里是将a和b加起来的结果输出出来,然后赋值给sum,最后打印sum.
这里不用return而使用echo直接将值输出输出,避免了return返回值只有0-255之间的问题.通过直接输出然后赋值给sum,最后再由echo $sum输出最后的结果.
#!/bin/bash function add(){ s=$[$1 + $2] echo $s } read -p "请输入第一个整数: " a read -p "请输入第二个整数: " b sum=$(add $a $b) echo "和: "$sum
文本处理工具
1.cut
cut [选项参数] filename
说明:默认分隔符是制表符
2)选项参数说明
-f 列号,提取第几列
-d 分隔符,按照指定分隔符分割列,默认是制表符“\t” -
c 按字符进行切割 后加加 n 表示取第几列 比如 -c 1
2.awk
awk [选项参数] ‘/pattern1/{action1} /pattern2/{action2}...’ filename
pattern:表示 awk 在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令
2)选项参数说明
-F 指定输入文件分隔符
-v 赋值一个用户定义变量
3)awk 的内置变量
FILENAME 文件名 NR 已读的记录数(行号)
NF 浏览记录的域的个数(切割后,列的个数
遇到的问题
java与scala的版本冲突导致
Error:scalac: error while loading package, Scala signature package has wrong version-CSDN博客
需编译器添加scala的sdk版本与pom文件的版本一致
总结
今天将最后shell部分的内容学习完了,学会了使用cut和awk进行处理文本信息,然后配置了scala的环境,感觉scala的环境配置跟Java是差不多的,而且scala也兼容Java,编写scala的时候需要创建Maven项目,然后配置scala的配置,才能启动。
10月23日 黑马Scala
学习内容:
伴生对象,注释,变量与数据类型,类型转换,运算符,条件分支
视频链接:
019尚硅谷Scala变量和数据类型(七)数据类型系统哔哩哔哩bilibili
摘要
Scala伴生对象
Scala 中没有 static 关键字,但是又需要有static的作用,就需要使用Scala中的单例对象:Object,伴生对象和伴生类是同一个名字,可以互相访问private属性
object ClassDemo12 { //1. 定义一个类Generals, 作为一个伴生类. class Generals { //这里写的都是非静态成员. //2. 定义一个toWar()方法, 输出一句话, 格式为"武将拿着**武器, 上阵杀敌!" def toWar() = println(s"武将拿着${Generals.armsName}武器, 上阵杀敌!") } //3. 定义一个伴生对象, 用来保存"武将的武器". object Generals { //这里写的都是静态成员. private var armsName = "青龙偃月刀" } //定义main方法, 作为程序的主入口 def main(args: Array[String]): Unit = { //4. 创建Generals类的对象. val g = new Generals //5. 调用Generals类中的toWar方法 g.toWar() } }
三引号
方便我们定义多行文本的字符串,字符串中也可以使用字符串模版的形式(${}),stripMargin方法可以帮助我们去除每行开头的空格和
|
符号
// 三引号表示字符串,保持多行字符串的原格式输出 val sql = s""" |select * |from | student |where | name = ${name} |and | age = ${age} |""".stripMargin println(sql)
文件读取与写入
Scala之文件读取与写入scala读取文件的方法大数据老人家i的博客-CSDN博客
这里读取文件不仅仅可以使用foreach将文件中的内容print打印到控制台中,同样可以跟Java一样以行读取数据使用getLines,Scala没有内置的对文件写入的方法,所以这里使用Java的输出流然后对文件进行写入。
def main(args: Array[String]): Unit = { // 1.从文件中读取数据 Source.fromFile("src\\main\\resources\\test.txt").foreach(print) // 2.将数据写入文件 val writer = new PrintWriter(new File("src\\main\\resources\\output.txt")) writer.write("hello scala from java writer") writer.close() }
遇到的问题
连续使用toInt和toString出现错误的情况
老师这样写的时候运行是成功的,但是我运行这个会运行失败
scala - "does not take parameters"链接方法调用时没有句点 - IT工具网 (coder.work)
但是先将7.5转成Int,然后再转成String 就可以实现.
在这篇博客中说这种形式是非正式的,不能像这样链接无参数方法调用。
总结
今天学习Scala中的一些常用的数据类型,运算符等,感觉这部分的内容跟Java基本是一样的,大差不差,但是Scala对于面对对象更加彻底,连对于算数运算这些也是相当于对象的方法调用,然后学习了if语句,if语句是一样的,虽然Scala没有三元运算符但是省略的写法,可读性更强,写的也挺简单的.
10月24日 黑马Scala
学习内容:
For循环,While循环,函数与方法,函数参数特殊用法,函数至简原则
视频链接:
038尚硅谷Scala流程控制(二)For循环(二)不包含边界的范围遍历哔哩哔哩_bilibili
摘要
For循环
一.范围遍历
1.包括结束范围
使用to将范围进行连接,包含了开头和结束范围
for (i <- 1 to 10) { println(i + ".hello world") }
2.不包括结束范围
使用Range和until的方式进行遍历,这样遍历出来的不会包括结束的范围,Range的方式跟python中for循环的写法很相似,是将1到10(不包括10)的数,封装到集合中,然后再从集合中进行遍历,until跟to差不多就是不包括结束范围.
for (i <- Range(1, 10)) { println(i + ".hello world") } for (i <- 1 until 10) { println(i + ".hello world") }
二.循环守卫
循环时可以增加条件来决定是否继续循环体的执行,比如可以,循环到5的时候不打印5,其他正常进行打印.
for (i <- 1 to 10 if i != 5) { println(i) }
三. 循环步长
可以设置循环直接的步长(也就是两个数之间差了多少),使用by 后面写步长
如果想要进行倒序的话可以使用reverse反转就可以反着打印,其实底层原理也就是将开始和结束范围反过来然后步长变为相反数,然后进行遍历.
// 4.循环步长(step 步长不能为0) for (i <- 1 to 10 by 2) { println(i) } // 倒序可以使用reverse println("------------------") for (i <- 1 to 10 reverse) { println(i) }
四. 循环返回值
scala所有的表达式都是有返回值的,但是返回值并不一定都是有值的,for循环返回值为Unit
若需要将for循环的结果作为返回值使用,需要采用yield关键字,yield关键字会把每次循环结果放置在一个新的结果中
val a: immutable.IndexedSeq[Int] = for (i <- 1 to 10) yield i println("a = " + a)
五.循环中断
Scala中没有像Java中的break,continue这样的,可以对循环进行中断的关键字,使用了Breaks可以进行中断,实现异常的抛出和捕捉
底层的逻辑其实就是使用了抛出异常的方式,然后进行退出循环.
Breaks.breakable( for (i <- 0 until 5) { if (i == 3) { Breaks.break() } println(i) } )
遇到的问题
无
总结
今天学习的内容主要是对Scala的流程控制中的For循环进行学习,这部分内容其实跟Java中很相似,但是感觉Scala书写起来更加的简洁明了,甚至连循环也有返回值,在循环中断中,没有了break和continue而是使用Breaks进行包裹,中间使用break进行中断.书写的时候还有至简原则,尽量的简写.
10月25日 黑马Scala
学习内容:
匿名函数,闭包,柯里化
视频链接:
053尚硅谷Scala函数式编程(三)函数高级(一)匿名函数(一)概念及简化规则哔哩哔哩bilibili
摘要
匿名函数
对于匿名函数来说在Java中也有,只不过对于Scala中的匿名函数来说,Scala更加的简洁
匿名函数至简原则
1.参数的类型可以省略,会根据形参进行自动的推导
2.类型省略之后,发现只有一个参数,则圆括号可以省略;其他情况:没有参数和参 数超过 1 的永远不能省略圆括号。
3.匿名函数如果只有一行,则大括号也可以省略
4.如果参数只出现一次,则参数省略且后面参数可以用_代替
// 实际示例,定义一个"二元运算"函数 只操作1和2两个数,但是具体运算通过参数传入 def dualFunctionOneAndTwo(fun: (Int, Int) => Int): Int = { fun(1, 2) } // 匿名函数简化 println("---------化简前-----------") println(dualFunctionOneAndTwo((a, b) => a + b)) println(dualFunctionOneAndTwo((a, b) => a - b)) println("---------化简后-----------") println(dualFunctionOneAndTwo(_ + _)) println(dualFunctionOneAndTwo(_ - _))
高阶函数
定义函数时格式:val 变量名 = (输入参数类型和个数) => 函数实现和返回值类型 “=>” 左面表示输入参数名称、类型和个数,右边表示函数的实现和返回值类型
第一种书写的方式是最原始的方式,就是进行正常的书写函数调用和返回函数
第二种书写的方式是采用匿名函数,省去了中间函数的名称和返回值的类型让Scala自行判断.
第三种书写的方式是柯里化,是把原来接受多个参数的函数变换成接受一个参数的函数过程,并且返回接受余下的参数且返回结果.
def func(i: Int): String => (Char => Boolean) = { def f1(s: String): Char => Boolean = { def f2(c: Char): Boolean = { if (i == 0 && s == "" && c == '0') false else true } f2 } f1 } // 匿名函数简写 def func1(i: Int): String => (Char => Boolean) = s => c => if (i == 0 && s == "" && c == '0') false else true // 柯里化 def func2(i: Int)(s: String)(c: Char): Boolean = { if (i == 0 && s == "" && c == '0') false else true }
遇到的问题
无
总结
今天学习的内容主要围绕着匿名函数和高阶函数展开,对于匿名函数来说,虽然学过但是他的书写方式有点复杂的感觉,感觉使用柯里化的方式去书写更加的简便和利于阅读代码,还学习了闭包的意思可以访问不再当前作用范围的函数.
10月26日 黑马Scala
学习内容:
尾递归,传名参数,传值参数,惰性加载,自定义While循环
视频链接:
065尚硅谷Scala函数式编程(三)函数高级(五)递归(二)尾递归优化哔哩哔哩bilibili
摘要
尾递归
递归是通过函数内部调用函数本身从而完成函数体,可能会出现调用次数过多出现栈溢出的问题,而尾递归是通过参数传递每一次的调用结果,达到不像递归一样会出现压栈的情况.
当我们想要验证尾递归是否是正确的时候可以使用@tailrec注解.
// 递归实现 def fact(n: Int): Int = { if (n == 0) return 1 fact(n - 1) * n } // 尾递归实现 def tailfact(n: Int): Int = { @tailrec def loop(n: Int, currRes: Int): Int = { if (n == 0) return currRes loop(n - 1, currRes * n) } loop(n, 1) }
自定义While循环
开始使用的时候可以闭包+递归+控制抽象 递归的方式,这种方式比较的复杂,但是后面使用柯里化,只需要考虑里面的参数的变化从而确定是使用传名参数,也省略了内部函数的名称.
// 2.用闭包实现一个函数,将代码块作为参数传入,递归调用 def myWhile(condition: => Boolean): (=> Unit) => Unit = { // 内层函数需要递归调用,参数就是循环体 def doLoop(op: => Unit): Unit = { if (condition) { op myWhile(condition)(op) } } doLoop _ } // 柯里化实现 def myWhile3(condition: => Boolean)(op: => Unit): Unit = { if (condition) { op myWhile3(condition)(op) } }
遇到的问题
无
总结
今天学习了像尾递归,在Java等语言中学习过递归的概念,递归是自身调用自身,但是是保持调用堆栈,容易因为栈的堆积,而导致溢出,但是尾递归就是将每一次调用后的函数将结果返回成为下一次调用的参数,这样就不会形成栈堆积的情况.然后就是学习了控制抽象,有三种传值参数,传名参数,惰性加载,传名参数就是将未计算的表达式直接传入到函数中,而惰性加载lazy就是在开始的时候并不执行,直到调用的时候才进行加载.感觉还是能够理解的.
10月30日 制作双绞线及服务器修复
遇到的问题
FTP服务器异常
发现是因为FTP服务器,那个师傅把线接错了,接到了另外一个路由器去,所以导致了无法访问FTP,需要将水晶头两端,一端接在FTP服务器,另一端接在黑色的那个路由器上,然后就可以正常访问到工作室的FTP服务器了.
项目存储服务器网络异常
显示出的错误是因为交换机网线,或者是配置问题,我们先检查了对端交换机的网线接的是没有问题的,所以将问题锁定在配置问题上,我们也无法确定问题在哪里,然后听学长说重置一下就可以了.
UltraISO(软碟通)制作U盘启动盘完整教程 - 知乎 (zhihu.com)
需要先使用U盘制作PE启动盘,这个部分在之前重装了台式机重装成Ubuntu有一定的经验,所以制作这个启动盘还是没有什么问题的.
最后是将u盘插入到服务器上,然后重新配置服务器,这个部分也遇到了问题,就是配置完之后一直重新要配置,最后发现配置一次后,需要将u盘拔出就可以了.
最后进入192.168.123.254:8080 就可以正常的加入电池组,配置相关的设置.网络这个部分也正常了.
总结
今天学习了制作双绞线,制作起来确实有一定的难度,因为把原来的四捆线解开之后,线都是弯曲的不好弄直,需要先将中间段弄直后,然后用剪线钳将前端的线剪掉,最后插入到水晶头中,再使用钳子压一下水晶头,然后就好了,测试的时候连接交换机,然后插自己电脑,改完ip地址看看是否能够上大数据的网站,然后直接成功了.也将自己新做的双绞线来连接FTP服务器和路由器.然后下午重置了项目部署服务器,让之前的网络问题解决掉了.今天虽然没有学习其他的内容,但是在修网络和制作双绞线中也学习到很多.也是收获满满的一天.
10月31日 黑马Scala
学习内容:
导包,构造器,继承,多态,抽象类,伴生对象.
视频链接:
070尚硅谷Scala面向对象(一)包(一)声明和访问哔哩哔哩_bilibili
摘要
@BeanProperty
能够自动生成Java的get/set方法.
注意: 不能用在private修饰的属性上
如果属性是__,如果是String表示是空,如果是Int类型就是0.
// 定义一个类 class Student { // 定义属性 private var name: String = "alice" @BeanProperty val age: Int = 18 var sex: String = _ }
构造器
在Scala中一个类只能有一个主构造器,辅助构造器的名字必须是this ,而且辅助构造器第一行必须调用主构造器,辅助构造器可以进行重载.
class Student1() { // 定义属性 var name: String = _ var age: Int = _ println("1. 主构造方法被调用") // 声明辅助构造方法 def this(name: String) = { this() // 直接调用主构造器 println("2. 辅助构造方法一被调用") this.name = name println(s"name: $name age: $age") }
推荐使用的构造器参数方式
直接当成主构造方法的形参,相当于内部已经当成属性来使用,将传入参数和赋值全都省略了.
class Student3(var name: String, var age: Int)
还可以使用这种方式进行无参的构造
// 无参构造器 class Student2 { // 单独定义属性 var name: String = _ var age: Int = _ }
伴生对象
伴生对象的第一个意义就是弥补类中不能定义static属性的缺陷,第二个意义就是对于伴生对象也生成的是静态属性,所以不会出现实例属性内存溢出的情况,也就是节省内存资源.第三个意义就是静态属性开辟一块内存空间,我们可以在所有实例中共享这块内存里的信息,也就是资源共享.
class Student11(val name: String, val age: Int) { def printInfo(): Unit = { println(s"student: name = $name, age = $age, school = ${Student11.school}") } } // 伴生对象 object Student11 { val school: String = "atguigu" // 定义一个类的对象实例的创建方法 def newStudent(name: String, age: Int): Student11 = new Student11(name, age) def apply(name: String, age: Int): Student11 = new Student11(name, age) }
使用newStudent的创建对象就是正常的创建,apply的话也是同样创建,但是在调用的时候直接可以用类名调用跟上参数就可以了.
单例设计模式
懒汉式: 是真正用到的时候才去建这个单例对象.
饿汉式: 不管用不用,一开始就建立 这个单例对象.
// 饿汉式 object Student12 { private val student: Student12 = new Student12("alice", 18) def getInstance(): Student12 = student } // 懒汉式 object Student12 { private var student: Student12 = _ def getInstance(): Student12 = { if (student == null) { // 如果没有对象实例的话,就创建一个 student = new Student12("alice", 18) } student } }
遇到的问题
无
总结
今天学习的内容学习了使用Beanproperty注解,他的作用相当于java构造set/get方法,构造器的话分为主构造器和辅助构造器两种,如果是辅助构造器的话,在第一行就需要调用主构造器,辅助构造器可以对主构造器进行重载操作,推荐的方式就是直接将参数作为主构造器的参数,然后是一个不同于java的概念就是伴生对象,就是相当于用于解决java中有static关键字,而Scala中没有的问题.总体上来说还是能够理解的.
11月1日 黑马Scala
学习内容:
特质的混入,特质的叠加,钻石问题的特质叠加,类型检测和转换,枚举类和应用类
视频链接:
084尚硅谷Scala面向对象(八)特质(二)特质的混入哔哩哔哩_bilibili
摘要
特质
Scala中没有多继承,跟单例对象很像,但单例对象是具体的,特质是抽象的,但是不需要abstract修饰.如果需要的话可以使用with混入类或者是其他特质中
// 定义一个特质 trait Young { // 声明抽象和非抽象属性 var age: Int val name: String = "young" // 声明抽象和非抽象的方法 def play(): Unit = { println("young people is playing") } def dating(): Unit } class Student13 extends Person13 with Young { // 重写冲突的属性 override val name: String = "student" // 实现抽象方法 def dating(): Unit = println(s"student $name is dating") def study(): Unit = println(s"student $name is studying") // 重写父类方法 override def sayHello(): Unit = { super.sayHello() println(s"hello from: student $name") } }
注意: 如果父类和trait中有同样的属性或者方法,需要重写这个属性或者是方法,否则在运行的时候就会出现冲突.
动态混入
动态混入就是在不修改原来代码的情况下扩展功能,也就是说原本需要with Talent这个特质,但是创建其他对象的时候不需要这个,所以就使用这种创建方式只给个别的类添加特质,然后重写里面的方法.
// 动态混入 val studentWithTalent = new Student14 with Talent { override def singing(): Unit = println("student is good at dancing") override def dancing(): Unit = println("student is good at singing") } studentWithTalent.singing() studentWithTalent.dancing()
叠加特质
此时继承调用的时候最后调用increase方法最后输出的是Knowledge15中的increase方法,因为scala中实现和继承是从后往前的,跟父子没有关系,所以最后调用的是Knowledge中的increase方法.
class Student15 extends Person13 with Talent15 with Knowledge15 { override def singing(): Unit = println("dancing") override def dancing(): Unit = println("singing") override def increase(): Unit = { super.increase() }
特质自身类型
有点像继承和特质的混入有点像,指明类型之后就可以调用User中的name属性了
trait UserDao { _: User => // 当数据库插入数据 def insert(): Unit = { println(s"insert into db: ${this.name}") } }
特质和抽象类的区别
优先使用特质,一个类只能扩展一个抽象类,但是能扩展多个特质
如果需要构造函数参数,使用抽象类,因为抽象类中可以定义但参数的构造函数,但是特质不行(有无参构造)
遇到的问题
主要的问题是现在不知道name是什么,在父类和trait的中都有name属性,进行了冲突.
所以需要重写冲突的属性
// 重写冲突的属性 override val name: String = "student"
总结
今天学习了trait特质,这个的概念很像java中接口的概念,动态混入的话就是在不改变原来代码的情况下,仅仅给个别类添加新的特质的方式叠加特质的话就是创建一个特质后,再在特质的基础上再添加特质,如果直接调用super的话调用的时候最后with的那个特质中的方法.还学习了判断类型和对类型对象进行强转的方法,今天的学习还是比较的轻松的难度没有很大.
11月2日 黑马Scala
学习内容:
不可变数组,可变数组,可变数组与不可变数组的转化,多维数组.
视频链接:
098尚硅谷Scala集合(二)数组(二)可变数组(三)添加元素哔哩哔哩bilibili
摘要
集合
建议: 在操作集合的时候,不可变用符号,可变用方法.
不可变数组
两种创建数组的方式
// 1. 创建数组 val arr: Array[Int] = new Array[Int](5) // 另一种创建方式 val arr2 = Array(12, 37, 42, 58, 97)
数组的遍历
这里有多种遍历数组的方法,比如像普通的for循环,增强for,迭代器,foreach的方式.
感觉自己写的话可能会使用增强for的方式,但是foreach化简后的方式是最简便的,但是这个可读性有点差,感觉自己会不记得这个的意思.
// 1.普通for循环 for (i <- arr.indices) println(arr2(i)) // 2. 直接遍历所有元素,增强for循环 for (elem <- arr2) println(elem) // 3.迭代器 println("迭代器") val iter = arr2.iterator while (iter.hasNext) println(iter.next()) // 4. 调用foreach方法 println("foreach") arr2.foreach((elem: Int) => println(elem)) println("化简后") arr2.foreach(println) println(arr2.mkString("[", ",", "]"))
可变数组
添加元素
添加元素的方式有很多,可以使用:+,+:等方式添加或者使用.+=的方式添加。但是这些方式都不是很清楚,而且容易弄混。
所以建议使用的是调用方法的方式去添加,这样更简单明了。也增加了可读性。
arr1.append(36) arr1.prepend(11, 76) arr1.insert(1, 23, 54) arr1.insertAll(1, newArr1) arr1.prependAll(newArr2)
多维数组
创建多维数组
创建的是一个两行三列的数组
// 1. 创建二维数组 val array: Array[Array[Int]] = Array.ofDim[Int](2, 3)
多维数组遍历
有多种方式去遍历,第一种是直接将两行循环写在一行上直接进行打印,第二种方式使用indices的方式进行打印,最后一种是使用foreach的方式进行打印,这种方式最简单,直接写在一行上,如果层数更多就将_.foreach再写在foreach中。
for (i <- 0 until array.length; j <- 0 until array(i).length) { println(array(i)(j)) } for (i <- array.indices; j <- array(i).indices) { print(array(i)(j) + "\t") if (j == array(i).length - 1) println } array.foreach(line => line.foreach(println)) array.foreach(_.foreach(println))
列表
创建列表(可变或不可变)
// 1. 创建不可变列表 val list1 = List(1, 2, 3) // 1. 创建可变列表 val list1 = new ListBuffer[Int]() val list2 = ListBuffer(12, 53, 75)
添加元素
添加元素的时候可以使用+: 或者是使用:: 创建列表,但是如果是两个列表只会将列表直接加在前面.
Nil的意思相当于一个空列表.
val list2 = 10 +: list1 val list3 = list1 :+ 23 val list4 = list2.::(51) val list5 = Nil.::(13) val list6 = 89 :: 32 :: Nil val list7 = 17 :: 28 :: 48 :: 39 :: 98 :: Nil
合并列表
将两个列表拼接在一起,两种写法的意思是一样的.
val list9 = list6 ::: list7 val list10 = list6 ++ list7
遇到的问题
无
总结
今天学习了数组,数组分为三种不可变数组,可变数组,多维数组,创建方式基本就是直接new或者是直接Array然后在()中写里面的元素.数组的遍历方式跟java也基本相同也是使用for循环或者是使用foreach的方式进行遍历.然后是添加元素,添加元素的话其实方式还是很多的,但是建议还是采用最基本的使用.方法名进行添加的方式进行添加,其他方式的话都是符号可能理解起来不是很容易.