项目中遇到的一些问题(基于SSM实现的电商系统)

1.什么是MD5加密?

MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。虽然现在破解MD5工具随处可见,但是我们可以使用在要加密的内容前加上特殊的一段“标记”,以此来避免破解。
在Java中有两种使用MD5加密的方式:

  • java自带jar工具MessageDigest实现
  • spring自带的工具DigestUtils实现

2.为什么要重写hashcod和equal方法?

首先来看下上文提到的integer的源码

@Override
public int hashCode() {
    return Integer.hashCode(value);
}
 
public static int hashCode(int value) {
    return value;
}
 
public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

如Integer类中equals方法和hashcode方法均被重写,Integer类中的hashcode方法就是返回它本身的值,equals方法比较的是它本身的值是否相等。

而equals方法必须要满足以下几个特性

1.自反性:x.equals(x) == true,自己和自己比较相等

2.对称性:x.equals(y) == y.equals(x),两个对象调用equals的的结果应该一样

3.传递性:如果x.equals(y) == true y.equals(z) == true 则 x.equals(z) == true,x和y相等,y和z相等,则x和z相等

4.一致性 : 如果x对象和y对象有成员变量num1和num2,其中重写的equals方法只有num1参加了运算,则修改num2不影响x.equals(y)的值

而这时如果某个类没有重写hashcode方法的话,equals判断两个值相等,但是hashcode的值不相等,如String类,这样就会造成歧义,所以当我们重写equal时必定要重写hashcode方法
  
如果只重写equals()方法后不重写hashCode()方法,可能回达不到预期的效果,比如hashMap中key值是通过hashCode()方法获取哈希值,获取值的哈希值是与内存地址相关联的,如果一个对象重写equals方法,根据equals的五个原则中的传递性原则,不同地址但是相同内容的对象返回是true,但是两个对象的hashCode值是不同的,所以说在hashMap只是根据条件调用get(key)方法时(这里只是get()方法,前提是只有一个对象调用了put()方法,如果两个对象都调用了put()方法,这时value值是不会覆盖的,get()两个对象回查出不同的两个值,会查不到预期的效果,只有一个能查出来。另一个为null。

3.vo bo pojo层代表什么?

PO / BO / VO / DTO / POJO等多种命名形式的类其实是对JavaBean一个较好的区分,虽然没有硬性的要求,但是这样的命名规范确实是一个很好的习惯。

PO :persistent object 持久对象
有时也被称为Data对象,对应数据库中的entity,可以简单认为一个PO对应数据库中的一条记录。

PO命名的Java对象通常以数据库表为单位。

BO :business object 业务对象
封装业务逻辑为一个对象(可以包括多个PO,通常需要将BO转化成PO,才能进行数据的持久化,反之,从DB中得到的PO,需要转化成BO才能在业务层使用)。
BO命名的Java对象通常主要是以业务为单位,而不是数据库表。

VO :value object值对象 / view object表现层对象
1 .对应页面显示的数据对象。
2 .对应提供接口请求或者响应的数据对象。
意味着我们可以将返回给页面的实体对象命名为 XxxVO,同时也可以将一个接口的请求和响应对象分别命名为RequestXxxVO和ResponseXxxVO。

DTO (TO) :Data Transfer Object数据传输对象
DTO通常表示数据传输过程承载的数据。比如一张表有100个字段,那么对应的PO就有100个属性(大多数情况下,DTO 内的数据来自多个表)。但view层只需显示10个字段,没有必要把整个PO对象传递到Client,这时我们就可以用一个带有10个属性的DTO来传输数据到Client,这样也不会暴露Server端表结构。到达客户端以后,如果用这个对象来对应界面显示,那此时它的身份就转为VO。

POJO :plain ordinary java object 无规则简单java对象 。
一个中间对象,可以转化为PO、DTO、VO。 通常POJO所表示的范围比较广,如果想对系统中各个实体表示的意义比较明确,不建议使用该类命名。
1 .POJO持久化之后 ==〉 PO
2 .POJO传输过程中 ==〉 DTO
3 .POJO用作表示层 ==〉 VO

4.静态块是什么?

static是Java中的一个关键字,我们不能声明普通外层类或者包为静态的。static用于下面四种情况。

静态变量:我们可以将类级别的变量声明为static。静态变量是属于类的,而不是属于类创建的对象或实例。因为静态变量被类的所有实例共用,所以非线程安全的。通常静态变量还和关键字final一起用,作为所有对象共用的资源或常量。如果静态变量不是私有的,那么可以通过ClassName.variableName来访问它。

静态方法:类似于静态变量,静态方法也属于类,不属于实例的。静态类只能访问类的静态变量,或调用类的静态方法。通常静态方法作为工具方法,被其它类使用,而不需要创建类的实例。譬如集合类、Wrapper类(String, Integer等)和工具类(java.util中的类)都有很多静态方法。通常java程序的开始就是一个main()方法,它就是个静态方法。

静态块:静态块就是类加载器加载对象时,要执行的一组语句。它用于初始化静态变量。通常用于类加载的时候创建静态资源。我们在静态块中不能访问非静态变量。我们可以在一个类中有多个静态块,尽管这么做没什么意义。静态块只会在类加载到内存中的时候执行一次。

静态类:我们对嵌套类使用static关键字。static不能用于最外层的类。静态的嵌套类和其它外层的类别无二致,嵌套只是为了方便打包。

当在Java中new一个类时,java对于这个类内容的执行顺序是:
父类静态块->子类静态块->父类构造块->父类构造函数->子类构造块->子类构造函数

5.分页查询是什么

使用SELECT查询时,如果结果集数据量很大,比如几万行数据,放在一个页面显示的话数据量太大,不如分页显示,每次显示100条。

要实现分页功能,实际上就是从结果集中显示第1100条记录作为第1页,显示第101200条记录作为第2页,以此类推。

因此,分页实际上就是从结果集中“截取”出第M~N条记录。这个查询可以通过LIMIT OFFSET 子句实现。

例:SELECT id, name, gender, score FROM students ORDER BY score DESC LIMIT 3 OFFSET 0;

这里我们把结果集分页,每页3条记录。要获取第1页的记录

如果要查询第2页,那么我们只需要“跳过”头3条记录,也就是对结果集从3号记录开始查询,把OFFSET设定为3:SELECT id, name, gender, score FROM students ORDER BY score DESC LIMIT 3 OFFSET 3;

6.String,StringBuffer,StringBuilder的区别?

String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
String S1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个
String S1 = “This is only a” + “ simple” + “test”; 其实就是:
String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如:
String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
这时候 JVM 会规规矩矩的按照原来的方式去做

在大部分情况下 StringBuffer > String
StringBuffer
Java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append(“le”) 会使字符串缓冲区包含“startle”,而 z.insert(4, “le”) 将更改字符串缓冲区,使之包含“starlet”。
在大部分情况下 StringBuilder > StringBuffer
java.lang.StringBuilde
java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。

7.ftp与nginx是如何合作的?

我们在项目中使用vsftp开放访问服务器,使使用者可以上传他们想要的信息到服务器上,而nginx正好与ftp相反,它映射FTP图片资源文件,读取展示图片给用户。一般用来输出支付二维码给用户

8.el表达式详解

EL只能从四大域中获取属性
el
el

9.count(1)代表什么?

count(1),其实就是计算一共有多少符合条件的行.
1并不是表示第一个字段,而是表示一个固定值.
其实就可以想成表中有这么一个字段,这个字段就是固定值1,count(1),就是计算一共有多少个1…
同理,count(2),也可以,得到的值完全一样,count(‘x’),count(‘y’)都是可以的.一样的理解方式.在这个语句理都可以使用,返回的值完全是一样的.就是计数.
count(*),执行时会把星号翻译成字段的具体名字,效果也是一样的,不过多了一个翻译的动作,比固定值的方式效率稍微低一些.

10.枚举类型,接口的默认方法与静态方法
枚举
接口

11.ssm和前端如何交互?

本项目中只是使用http://localhost:8080/user/login.do这种方式进行交互

Spring 负责的是各个 Java 对象的创建、维护、销毁这类操作,通常这些 Java 对象都会被称为 Bean,Spring 只是个管家的,你用 Spring 做 Web 也好,自己写点其他八杆子打不到边的东西也好,就是用来维护对象的。

SpringMVC 是一个 MVC 框架。你说的接口(前后端利用 HTTP 通信,传递参数并返回信息)、路由(URL 和 对应的方法/类之间的匹配关系)都是在这里面实现的。

MyBatis 是一个 ORM 工具,用来连接数据库的。增删查改都是在对数据库进行操作,就算你不做成 Web,做成一个本地的桌面软件,ORM 也是时常用到的。

12.guava缓存是什么?

guava

13.mybatis三剑客分别是?

1、MyBatis generator
利用mybatis-generator自动生成代码

2、MyBatis plugins

在IDEA中可以实现mybatis中dao层和xml之间的快速跳转。

3、MyBatis 分页插件 - PageHelper
官方介绍地址:

https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

总简介

14.redis简介
redis

15.Guava Cache内存缓存实现的token验证
token

16.HttpSession的正确理解

一个session就是一系列某用户和服务器间的通讯。服务器有能力分辨出不同的用户。一个session的建立是从一个用户向服务器发第一个请求开始,而以用户显式结束或session超时为结束。
其工作原理是这样的:
1.当一个用户向服务器发送第一个请求时,服务器为其建立一个session,并为此session创建一个标识号;
2.这个用户随后的所有请求都应包括这个标识号。服务器会校对这个标识号以判断请求属于哪个session。
这种机制不使用IP作为标识,是因为很多机器是通过代理服务器方式上网,没法区分每一台机器。
对于session标识号(sessionID),有两种方式实现:cookies和URL重写。

HttpSession的使用
我们来看看在API中对session是如何定义和操作的。
当需要为用户端建立一个session时,servlet容器就创建了一个HttpSession对象。其中存储了和本session相关的信息。所以,在一个servlet中有多少个不同用户连接,就会有多少个HttpSession对象。
使用的机理是:
1.从请求中提取HttpSession对象;
2.增加或删除HttpSession中的属性;
3.根据需要关闭HttpSession或使其失效。

在请求中有两个重载的方法用来获取HttpSession对象。
HttpSession getSession(boolean create)/getSession();作用是提取HttpSession对象,如果没有自动创建。

获取到HttpSession对象后,我们就需要使用HttpSession的某些方法去设置和更改某些参数了。如:
void setAttribute(String name, Object value);
Object getAttribute(String name);
void removeAttribute(String name);

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值