大数据培训实习 | 笔记

引言 idea 配置

idea 添加 Tomcat

修改现在的 Configuration 下图为添加新 Configuation JSP 重写父类方法 Alt+Insert

获得客户机请求参数

    getParameter(String) 方法(常用) getParameterValues(String name) 方法(常用) getParameterNames() 方法(不常用) getParameterMap() 方法(编写框架时常用)
提交 index.html 中的表单至服务器端处理 在服务器端使用 getParameter() 和 getParameterValues() 接收表单参数,代码如下:
1
2
3
4
5
6
7
8
9
10
11
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 客户端是以UTF-8编码提交表单数据的,所以需要设置服务器端以UTF-8的编码进行接收,否则对于 中文数据就会产生乱码
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");

System.out.println(username + " " + password);

request.getRequestDispatcher("/index.jsp").forward(request,response);
}

九个内置对象

Session: 一个会话:从浏览器与目标服务器建立连接,到浏览器关闭 什么是会话? 用户打开一个浏览器, 点击多个超链接, 访问服务器多个web资源, 然后关闭浏览器, 整个过程称之为一个会话 一个会话内,数据共享
1

MVC Model-View-Controller 设计模式 View: HTML, JSP Controller: Servlet, Spring MVC Model: 传递,数据对象(Entity) 发展:纯Servlet -> 纯JSP -> MVC -> 三层架构

三层架构

从上至下调用,或者平级调用 controller->service->dao 补充: Java 发展史: 解耦,降低之间的依赖 Spring Cloud :微服务 Spring Boot : 微服务中一个服务的编写,Spring Boot 是 Spring Cloud 基础 Maven 参考: Maven 教程 | 菜鸟教程 Maven – Maven in 5 Minutes Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤 Maven 是一个 项目管理工具,可以对 Java 项目进行构建、依赖管理。 Maven 也可被用于构建和管理各种项目,例如 C#,Ruby,Scala 和其他语言编写的项目。

Maven 功能

Maven 能够帮助开发者完成以下工作: 构建 文档生成 报告 依赖 SCMs 发布 分发 邮件列表

约定配置

Maven 提倡使用一个共同的标准目录结构,Maven 使用约定优于配置的原则,大家尽可能的遵守这样的目录结构。如下所示:
目录 目的
${basedir} 存放pom.xml和所有的子目录
${basedir}/src/main/java 项目的java源代码
${basedir}/src/main/resources 项目的资源,比如说property文件,springmvc.xml
${basedir}/src/test/java 项目的测试类,比如说Junit代码
${basedir}/src/test/resources 测试用的资源
${basedir}/src/main/webapp/WEB-INF web应用文件目录,web项目的信息,比如存放web.xml、本地图片、jsp视图页面
${basedir}/target 打包输出目录
${basedir}/target/classes 编译输出目录
${basedir}/target/test-classes 测试编译输出目录
Test.java Maven只会自动运行符合该命名规则的测试类
~/.m2/repository Maven默认的本地仓库目录位置
Maven 的 Snapshot 版本与 Release 版本 1、Snapshot 版本代表不稳定、尚处于开发中的版本。 2、Release 版本则代表稳定的版本。

补充

1
mvn --version
常用 Maven 命令
1
2
3
4
5
6
7
8
9
10
11
12
13
mvn -v # 查看Maven版本

mvn compile # 编译

mvn test # 测试

mvn package # 打包

mvn clean # 删除 target

mvn install # 安装jar包到本地仓库中

mvn archetype:generate -DgroupId=co.hoteam -DartifactId=Zigbee -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false # 创建一个新工程
Maven 目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
my-app
|-- pom.xml
`-- src
|-- main
| `-- java
| `-- com
| `-- mycompany
| `-- app
| `-- App.java
`-- test
`-- java
`-- com
`-- mycompany
`-- app
`-- AppTest.java
src/main/java:java 类文件,Emp.java src/main/resources:资源文件,jdbc.propertis、application.xml src/test/java:用于测试的java类文件 src/test/resources:用于测试的资源文件 target:输出目录,所有的输出物都存放在这个目录下,class 文件 target/classes:编译后的class文件存放处 pom.xml:Maven项目的核心配置文件

Maven 仓库

pom.xml

POM 是 Project Object Model 的缩写,即项目对象模型。 pom.xml 基于 Maven 的项目配置核心文件,它包含了构建一个项目的主要信息, pom.xml
pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Maven (xxx.zip) 目录结构

bin目录:包含了maven运行的一些命令脚本 boot目录:包含的是类加载器的一些东西 conf目录:configuration配置的,保存一些配置文件的 lib目录:保存jar包的

Maven 配置

修改 Maven 本地仓库地址

D:\Program Files Portable\apache-maven-3.5.0\conf\settings.xml
settings.xml
1
2
3
4
5
6
7
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: {{hbeSeoContent}}#123;user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
<localRepository>D:/maven-repository</localRepository>
如上,修改 Maven 本地仓库地址为 D:/maven-repository PS:直接使用 Windows 路径分割符: \ 也可以

Maven 中央(远程)仓库

D:\Program Files Portable\apache-maven-3.5.0\conf\settings.xml
settings.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!-- mirrors
| This is a list of mirrors to be used in downloading artifacts from remote repositories.
|
| It works like this: a POM may declare a repository to use in resolving certain artifacts.
| However, this repository may have problems with heavy traffic at times, so people have mirrored
| it to several places.
|
| That repository definition will have a unique id, so we can create a mirror reference for that
| repository, to be used as an alternate download site. The mirror site will be the preferred
| server for that repository.
|-->
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
上面,修改为阿里镜像中央仓库 注意: 如果一个jar包已经在本地仓库中有了,就不会再次去重复下载。如果没有则会下载,判断依据是版本号。这样做的好处是可
以节约本地的一个空间存储。

Maven JDK版本

D:\Program Files Portable\apache-maven-3.5.0\conf\settings.xml
settings.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<profiles>
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>

idea 创建 Maven工程

quickstart 为没有页面 webapp 为有页面 完成后,修改 pom.xml 注意:下方将 1.7 改为了 1.8
pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.iss.zz</groupId>
<artifactId>Day2</artifactId>
<version>1.0-SNAPSHOT</version>

<name>Day2</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>

</dependencies>


</project>
idea中 修改 Maven

若没有 Maven

没有 Maven ,手动添加 jar 包,麻烦 Spring Spring MVC 是 Spring 加的一个模块 ORM: 对象关系映射 Object Relational Mapping OXM 映射 XML文件 SSM整合: Spring Mybatis

IoC

接口与实现类 映射
applicationContext.xml
1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="testService" class="com.iss.zz.service.impl.TestServiceImpl"></bean>

</beans>

AOC

面向切面编程(AOP)是通过提供另一种设计程序结构的方式来补充面向对象的编程(OOP)。 OOP中关键的单元模块是类,而在AOP中单元模块是切面。切面使模块化的关注点跨越了多个类型和对
象。例如,事务管理。 AOP是 Spring 框架的关键组件之一。虽然 Spring IoC 容器不依赖于AOP(这意味着不需要使用 AOP),但AOP是对 Spring IoC 的补充,以提供功能非常强大的中间件解决方案。 Spring AOP with AspectJ pointcuts Spring通过使用 Xml-schema 或 @AspectJ annotation ,提供了编写自定义切面的简单而强大的方法 。 这两种样式都提供了完全类型化的建议,保证了在使用了AspectJ切入点语言的同时仍然使用
Spring AOP进行编织。

Transaction management

修改启动配置-类

controller

注意:实践发现 @ResponseBody 是否添加 也会影响路由匹配,不知道为何
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@PostMapping("login")
@ResponseBody
public Emp login(String ename, String password) {
if (ename == null || ename.length() == 0) {
System.out.println("用户名或密码错误,请重新登录");
return null;
}
Emp emp = this.empService.login(ename, password);
if (emp == null) {
System.out.println("用户名或密码错误,请重新登录");
} else {
System.out.println("登录成功");
}
return emp;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@PostMapping("add")
@ResponseBody
public Emp add(@RequestBody Emp inputModel) {
// 参考: https://blog.csdn.net/originations/article/details/89492884
// @responseBody 注解 的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
//注意:在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。

// @RequestBody 注解则是将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。
// 1) 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;
// 2) 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

inputModel.setEmpno(222);

return inputModel;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
@GetMapping("/list")
public List<Emp> list(Integer num) {
// 注意:mapping 路由匹配,对形参列表敏感,此处必须传参 ?num=2 才能匹配到路径
// 注意:和 ASP.NET Core 不同,对 controller 中的方法路由,最前的 `/` 不敏感
// 即 list 和 /list 都匹配到 /emp/list
// 而不是 /list 匹配到 /list
List<Emp> list = new ArrayList<>();
for (int i = 0; i <num; i++) {
list.add(new Emp(1, "eqew", "eqwewqe"));
}

return list;
}
MyBatis ORM: 对象关系映射

insert 后获取新增记录的id

参考: 关于mybatis插入时获取id问题_freshman2020的博客-CSDN博客 mybatis使用mysql数据库插入后获取Id的值_Zzzz_zzzz_zz的博客-CSDN博客 方法一: 使用 keyProperty="empno" useGeneratedKeys="true" 但是这样设置后,并不能通过数字类型或字符串类型进行接收,而是将id赋值给xxx实体类中的id属性。
所以获取返回的id应该用xxx.getId()进行获取。 下面的 id 为 empno 成功,发现,MyBatis会自动将插入后的记录empno赋值回emp对象的empno(自定义类class属于引用类型,全局唯一,赋值改变跟随)
1
2
3
<insert id="myInsert2" parameterType="com.iss.spring.model.Emp" keyProperty="empno" useGeneratedKeys="true">
insert into emp(ename,job) values(#{ename},#{job})
</insert>
<insert>, <update>, <delete>片段返回受影响行数 方法二: select LAST_INSERT_ID() 后取返回,不写id值
1
2
3
4
5
6
<insert id="myInsert" parameterType="com.iss.spring.model.Emp">
<selectKey keyProperty="empno" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into emp(ename,job) values(#{ename},#{job})
</insert>
EmpServiceImpl.java
1
2
3
4
5
6
@Override
public Emp myInsert(Emp inputModel) {
int empno = this.empDao.myInsert(inputModel);
inputModel.setEmpno(empno);
return inputModel;
}
TODO:失败:empno始终为 1,不知为何,似乎这样始终返回受影响行数,那么又如何取到 LAST_INSERT_ID()

Mapper XML Files

​ MyBatis 的真正强大在于它的语句映射,这是它的魅力所在。由于它的异常强大,映射器的 XML 文 件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的 代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。
SQL 映射文件只有很少的几个顶级元素(按照应被定义的顺序列出): resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。 sql – 可被其它语句引用的可重用语句块。 insert – 映射插入语句。 update – 映射更新语句。 delete – 映射删除语句。 select – 映射查询语句。

Parameters

String Substitution 默认情况下,使用 #{}参数语法时,MyBatis 会创建 PreparedStatement 参数占位符,并通过 占位符安全地设置参数(就像使用 ? 一样)。 这样做更安全,更迅速,通常也是首选做法,不过有时你
就是想直接在 SQL 语句中直接插入一个不转义的字符串。 比如 ORDER BY 子句,这时候你可以:
1
ORDER BY {{hbeSeoContent}}#123;columnName}
这样,MyBatis 就不会修改或转义该字符串了。

Result Maps

1
2
3
4
5
6
7
<!-- 通过xml创建一个新的类型到数据库表的映射, 此类型 Emp 可用于其他片段 -->
<resultMap id="empMap" type="Emp">
<id property="id" column="empno"></id>
<result property="ename" column="ename"></result>
<result property="password" column="password"></result>
<result property="job" column="job"></result>
</resultMap>

Dynamic SQL

if

1
2
3
4
5
6
7
8
9
10
<select id="getEmpByParams" resultMap="empMap">
<include refid="empSQL"/>
where
<if test="ename != null">
ename = #{ename}
</if>
<if test="job != null">
job = #{job}
</if>
</select>

choose、when、otherwise

​ 有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况, MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
1
2
3
4
5
6
7
8
9
10
11
12
13
<select id="findActiveBlogLike" resultType="Blog"> 
SELECT * FROM BLOG WHERE state = 'ACTIVE'
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null"> AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>

trim、where、set

Advanced Result Maps

​ MyBatis 创建时的一个思想是:数据库不可能永远是你所想或所需的那个样子。 我们希望每个数据 库都具备良好的第三范式或 BCNF 范式,可惜它们并不都是那样。 如果能有一种数据库映射模式,完美
适配所有的应用程序,那就太好了,但可惜也没有。 而 ResultMap 就是 MyBatis 对这个问题的答案。 结果映射(resultMap) constructor – 用于在实例化类时,注入结果到构造方法中 idArg – ID 参数;标记出作为 ID 的结果可以帮助提高整体性能 id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能 result – 注入到字段或 JavaBean 属性的普通结果 association – 一个复杂类型的关联;许多结果将包装成这种类型 嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用 collection – 一个复杂类型的集合 嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用 discriminator – 使用结果值来决定使用哪个 resultMap case – 基于某些值的结果映射 嵌套结果映射 – case 也是一个结果映射,因此具有相同的结构和元素; 或者引用其它的结果映射

One To Many

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<resultMap id="departmentMap" type="Department"> 
<id column="deptno" property="deptno"/>
<result column="dname" property="dname"/>
<result column="loc" property="location"/>
<collection property="emps" ofType="Emp">
<id column="empno" property="empno"/>
<result column="ename" property="ename"/>
<result column="sex" property="sex"/>
<result column="job" property="job"/>
<result column="mgr" property="mgr"/>
<result column="hiredate" property="hiredate"/>
<result column="sal" property="sal"/>
<result column="comm" property="comm"/>
<result column="deptno" property="deptno"/>
</collection>
</resultMap>

<select id="getDepartment" parameterType="java.lang.Integer" resultMap="departmentMap">
select
a.deptno, a.dname, a.loc, b.empno, b.ename, b.sex, b.job, b.mgr, b.hiredate, b.sal, b.comm
from
dept a left join emp b on a.deptno = b.deptno where a.deptno = #{deptno}
</select>

Many To One

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<resultMap id="empMap" type="Emp"> 
<id column="empno" property="empno"/>
<result column="ename" property="ename"/>
<result column="sex" property="sex"/>
<result column="job" property="job"/>
<result column="mgr" property="mgr"/>
<result column="hiredate" property="hiredate"/>
<result column="sal" property="sal"/>
<result column="comm" property="comm"/>
<result column="deptno" property="deptno"/>
<association property="department" javaType="Department">
<id column="deptno" property="deptno"/>
<result column="dname" property="dname"/>
<result column="loc" property="location"/>
</association>
</resultMap>

<select id="getEmployee" parameterType="java.lang.Integer" resultMap="empMap">
select
a.empno, a.ename, a.sex, a.job, a.mgr, a.hiredate, a.sal, a.comm, b.deptno, b.dname, b.loc
from
emp a left join dept b on a.deptno = b.deptno where a.empno = #{empno}
</select>
Hadoop

环境准备

CentOS 7 Hadoop 2.9.2 Oracle JDK jdk-8u131-linux-x64.tar.gz SSH终端: MobaXterm

安装 Hadoop

上传 hadoop-2.9.2.tar.gz 到 home 目录 解压
1
tar -zxvf /home/hadoop-2.9.2.tar.gz -C /opt/
配置环境变量
1
vi /etc/profile
1
2
3
# set hadoop environment 
export HADOOP_HOME=/opt/hadoop-2.9.2
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
1
source /etc/profile
1
hadoop version

安装 JDK

上传 jdk-8u131-linux-x64.tar.gz 到 home 目录 解压
1
tar -zxvf /home/jdk-8u131-linux-x64.tar.gz -C /opt/
配置环境变量
1
vi /etc/profile
1
2
3
4
# set jdk environment 
export JAVA_HOME=/opt/jdk1.8.0_131
export CLASSPATH=$JAVA_HOME/lib/
export PATH=$PATH:$JAVA_HOME/bin
1
source /etc/profile
1
java -version

关闭防火墙

1
systemctl stop firewalld.service
1
systemctl disable firewalld.service

修改 hosts 文件

1
vi /etc/hosts
1
192.168.xxx.xxx hadoop
hadoop 为主机名

修改安全策略

1
vi /etc/selinux/config
1
SELINUX=disabled

Hadoop 配置

修改 hadoop-env.sh

1
vi /opt/hadoop-2.9.2/etc/hadoop/hadoop-env.sh
1
export JAVA_HOME=/opt/jdk1.8.0_131

修改 core-site.xml

指定 HDFS 的 NameNode 的地址,value 值是主机名加端口号,如果在 host 文件中添加了主机名 和 ip 映射,主机名也可以用 ip 地址换。
1
vi /opt/hadoop-2.9.2/etc/hadoop/core-site.xml
core-site.xml
1
2
3
4
5
6
7
8
9
10
<configuration> 
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/temp</value>
</property>
</configuration>

修改 hdfs-site.xml

指定 hdfs 保存数据的副本数量,伪分布式只有一个节点,所以这里填:1 。
1
vi /opt/hadoop-2.9.2/etc/hadoop/hdfs-site.xml
hdfs-site.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<configuration> 
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.name.dir</name>
<value>/home/hadoop/hdfs/name</value>
</property>
<property>
<name>dfs.data.dir</name>
<value>/home/hadoop/hdfs/data</value>
</property>
</configuration>

修改 mapred-site.xml

在 /opt/hadoop-2.9.2/etc/hadoop/ 目录下是没有 mapred-site.xml 文件的,我们可以通过命令创建:
1
cd /opt/hadoop-2.9.2/etc/hadoop/
1
cp mapred-site.xml.template mapred-site.xml
mapred-site.xml
1
2
3
4
5
6
<configuration> 
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>

修改 yarn-site.xml

1
vi /opt/hadoop-2.9.2/etc/hadoop/yarn-site.xml
yarn-site.xml
1
2
3
4
5
6
<configuration> 
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop</value>
</property>
</configuration>

初始化和启动

1、初始化
1
cd /opt/hadoop-2.9.2/etc/hadoop
1
hadoop namenode -format
2、启动测试
1
cd /opt/hadoop-2.9.2/etc/hadoop
1
start-all.sh
3、访问:http://192.168.xxx.xxx:50070/ Q&A Q: 什么是接口 ? 与抽象类区别 ? A:接口没有实现,不能被实例化,只有通过实现类实例化, 对类:单继承多实现, 类与类间依赖:new:类的对象创建 解决依赖:不再手动new,由 Spring 来 new, 控制反转(IoC,Inversion of Control) IoC 是一种设计模式,依赖注入是实现 IoC 的一种方式 依赖注入(Dependency Injection):1.构造器注入 2.属性注入 Q:IoC? DI? A: 参考: IOC和DI有什么区别? - 祁达方的回答 - 知乎 《EXPERT ONE ON ONE J2EE DEVELOPMENT WITHOUT EJB》第6章: IoC主要的实现方式有两种:依赖查找,依赖注入。(128页) 依赖注入是一种更可取的方式。(130页) Q: Spring 作用 ? A: 解耦 补充

idea快捷键

F7 调试-进入 下一行

单例模式

1.饿汉式:一开始就存为静态static,存在资源浪费 2.懒汉式:只有用到的时候,才new,并保存到静态static,不存在资源浪费,但存在线程安全问题 解决:线程安全,上lock线程锁,变成同步处理 优化:
1
2
3
4
5
6
7
8
9
10
public static Singleton getInstance() {
if (singleton == null) { // 检查是否要阻塞
synchronized (obj) { // synchronized (Singleton.class)
if (singleton == null) { // 是否要重新创建实例
singleton = new Singleton();
}
}
}
return singleton;
}
静态类中类:最终版本,解决了浪费资源,线程安全问题: Static Inner Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Singleton { 

private Singleton() {
}

public static Singleton getInstance() {
return SingletonInner.singleton;
}

/**
* 静态内部类默认不加载,只有使用的时候才加载。
* 加载顺序是:
* Singleton > getInstance() > SingletonInner > SingletonInner.singleton
*/
private static class SingletonInner {
private static final Singleton singleton = new Singleton();
}
}

SSH 连接 Docker 内 Ubuntu

参考: Docker Ubuntu上安装ssh和连接ssh_JustToFaith-CSDN博客 用ssh连接docker容器 - Jesse131 - 博客园 Linux系统安装docker并用ssh登录docker容器_hpf247的博客-CSDN博客_docker ssh 映射 SSH 连接用 22 端口
1
docker run -d -p 2222:22 my-hadoop
安装 宿主机 SSH 连接 Docker 内 Ubuntu 用 openssh-server
1
apt-get install openssh-server
设置一个root密码,后面登陆会用到
1
passwd
修改 SSH 配置文件
1
vim /etc/ssh/sshd_config
1
2
#PermitRootLogin prohibit-password
PermitRootLogin yes
补充:
1
2
3
4
5
PubkeyAuthentication yes # 启用公钥私钥配对认证方式 
AuthorizedKeysFile .ssh/authorized_keys # 公钥文件路径(和上面生成的文件同)
PermitRootLogin yes # root能使用ssh登录
ClientAliveInterval 60 # 参数数值是秒 , 是指超时时间
ClientAliveCountMax 3 # 设置允许超时的次数
重启 SSH 服务
1
/etc/init.d/ssh restart
宿主机 SSH 连接
1
ssh root@0.0.0.0 -p 2222
补充: 或者
1
ssh root@127.0.0.1 -p 2222
测试这里使用 容器IP 连接失败 参考 感谢帮助!