1、接口不能继承抽象类;接口可以继承接口;抽象类可以实现接口;
- 接口里的方法是不能有方法身体的,但抽象类的方法是可以有方法体的,继承后,在这一点上就会产生矛盾. 抽象类的方法体无法存在了呀;所以接口不能继承抽象类;
- 接口是可以被接口继承的;即通过关键字extends声明一个接口是另一个接口的子接口。由于接口中的方法和常量都是public,子接口将继承父接口中的全部方法和常量。
- 抽象类可以实现接口,当一个类声明实现一个接口而没有实现接口中所有的方法,那么这个必须是抽象类,即abstract类。
2、shiro权限过滤配置不拦截;
<!-- Shiro权限过滤过滤器定义 -->
<bean name="shiroFilterChainDefinitions" class="java.lang.String">
<constructor-arg>
<value>
/static/** = anon
/portal/** = anon
/userfiles/** = anon
${adminPath}/uploadThemePicture = anon
${adminPath}/sys/systemConfig/clearCache = anon
${adminPath}/mms/account/mmsMaterialAccount/mmscountJsonP = anon
<!-- MMS stack -->
${adminPath}/mms/inlib/mmsStackManage/stationData = anon
<!-- MMS cang -->
${adminPath}/mms/inlib/mmsStackManage/mmStackManageJsonP = anon
${adminPath}/**/content = anon
${adminPath}/**/saveContentFile = anon
${adminPath}/**/deleteTempFile = anon
${adminPath}/** = user
/act/rest/service/editor/** = perms[act:model:edit]
/act/rest/service/model/** = perms[act:model:edit]
/act/rest/service/** = user
/ReportServer/** = user
</value>
</constructor-arg>
</bean>
遇到的问题是:A系统通过httpClient跨域调用了B系统中的接口,结果调用失败,就是因为没有在A系统中放行接口的url;shiro进行了拦截;
3、restful:表现层状态转移;即用URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作。
restful中的几种请求方式如何看是否安全(脏读、幻读、不可重复读)和
幂等(多次操作成功的条件下,是否会对数据库造成不好的影响)?
post(insert)不安全不幂等;
get(select)安全且幂等;
- get:查询,安全且幂等;查找朋友,uri: test.cn/v1/friends
- post:新增,不安全且不幂等;增加一个朋友,uri: test.cn/v1/friends
- put:更新,不安全且幂等;修改一个朋友,uri: test.cn/v1/friends
- delete:删除,不安全且幂等;删除一个朋友,uri: test.cn/v1/friends
4、cors(跨域资源共享)可解决跨域问题;
- 跨域:域名不同/端口不同/协议不同;
- ajax同源策略:请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同;
- 其他解决方案:jsonp;httpclient;nginx;
5、悲观锁
- 解释:悲观的认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改;
- 实例:关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁;synchronized、Lock就是悲观锁的实现;
- 使用场景:适合写操作多的情况,先加锁可以保证写操作时数据正确;
6、乐观锁
- 解释:乐观的认为自己在使用数据时不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。如果这个数据没有被更新,当前线程将自己修改的数据成功写入。如果数据已经被其他线程更新,则根据不同的实现方式执行不同的操作(例如报错或者自动重试);
- 实现:版本号机制或者CAS算法(Compare and Swap,比较与交换,是一种无锁算法);《cas使得乐观锁不锁定资源也可以实现线程同步》
- 实例:java.util.concurrent包;
- 使用场景:适合读操作多的情况,不加锁可以提高读操作的性能;
7、二叉查找树(Binary Search Tree)
- 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 任意节点的左、右子树也分别为二叉查找树;
- 没有键值相等的节点(no duplicate nodes);
8、2-3查找树(2-3 Search Tree)
- 对于2节点,该节点保存一个key及对应value,以及两个指向左右节点的节点,左节点也是一个2-3节点,所有的值都比key有效,有节点也是一个2-3节点,所有的值比key要大。
- 对于3节点,该节点保存两个key及对应value,以及三个指向左中右的节点。左节点也是一个2-3节点,所有的值均比两个key中的最小的key还要小;中间节点也是一个2-3节点,中间节点的key值在两个跟节点key值之间;右节点也是一个2-3节点,节点的所有key值比两个key中的最大的key还要大。
- 如果中序遍历2-3查找树,就可以得到排好序的序列。在一个完全平衡的2-3查找树中,根节点到每一个为空节点的距离都相同。
9、StringUtils.isNumeric(str);//判断字符串是否全部为数字,返回boolean,如果是空字符串,返回true;
10、通过String类的format函数实现保留两位小数:String.format("%.2f", d);
11、//json对象/json数组对象,多次经过json序列化后仍然是json,不可以向需要转换成json的map中放入json的字符串,否则他就是一个字符串了,不是json数据了!
JSONArray jsonArray = JSON.parseArray(treeData);//把从中间表中查询出来的json字符串转换成json数组对象
hashMapHeader.put("data", jsonArray);//把json对象放到data健对应的值中(hashMapHeader需要转为json格式)
12、oracle中存储大文本数据
- 在oracle中用clob类型表示大文本类型(mysql中用text);
- oracle中,如果一个列的类型为varchar2,那么它不能直接转换为clob类型;
- 通常像图片、文件、音乐等信息就用BLOB字段来存储,先将文件转为二进制再存储进去;而像文章或者是较长的文字,就用CLOB存储;
- 导出表的时候,若表结构中有blob、clob字段,则不能导出为sql语句,只能导出为dmp文件;
13、类的修饰符只有public、abstract、final;
如果不写的话,默认为包访问权限,也就是同一个包的其他类可以访问该类;
他的子类肯定可以访问他,因为如果不在一个包中,都不能继承他;
14、关于事物的注解
- @Transactional 注解应该只被应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置。
- 注解不会被继承,所以建议把注解用到具体的类以及方法上,而不是用在接口以及方法声明上;
- xml中配置annotation-driven使得注解生效;并且需要配置id为transactionManager的bean;
15、mysql分页用limit关键字;
- Limit m,n语句:参数m是起始下标,它从0开始;参数n是返回的记录数。
16、oracle借助于rownum进行分页;
- Rownum表示一条记录的行号,值得注意的是它在获取每一行后才赋予.因此,想指定rownum的区间来取得分页数据在一层查询语句中是无法做到的,要分页还要进行一次查询;
//最内层的查询SELECT * FROM TABLE_NAME表示不进行翻页的原始查询语句。
//ROWNUM <= 40和RN >= 21控制分页查询的每页的范围---效率高
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM <= 40
)
WHERE RN >= 21
//在查询的最外层控制分页的最小值和最大值---效率低
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
)
WHERE RN BETWEEN 21 AND 40
/**这是由于CBO优化模式下,Oracle可以将外层的查询条件推到内层查询中,以提高内层查询的
执行效率。对于第一个查询语句,第二层的查询条件WHERE ROWNUM <= 40就可以被Oracle
推入到内层查询中,这样Oracle查询的结果一旦超过了ROWNUM限制条件,就终止查询将结果
返回了。
而第二个查询语句,由于查询条件BETWEEN 21 AND 40是存在于查询的第三层,而Oracle
无法将第三层的查询条件推到最内层(即使推到最内层也没有意义,因为最内层查询不知道
RN代表什么)。因此,对 于第二个查询语句,Oracle最内层返回给中间层的是所有满足条
件的数据,而中间层返回给最外层的也是所有数据。数据的过滤在最外层完成,显然这个
效率 要比第一个查询低得多。**/
17、一次性的从数据库读取过多的数据,会引起内存溢出的error,上线前数据量小不容易出现这个问题,但是上线后数据量大了可能就有了,所以尽量使用分页查询,这样的话,数据量再多,也只是查询了其中的一部分!
18、如果一次需要查询到的数据量过大的话,需要考虑需求是否合理,
对于千万级数据,应该避免全表扫描;
19、"SQL state [null],error code [17004]无效的列类型"错误的几种情况
a、类型不匹配:
sql片段中#{}中的参数应该加上jdbc的类型:#{student.name,jdbcType=VARCHAR};
注意:MyBatis 插入空值时,需要指定JdbcType,否则报错“无效的列类型: 1111”;
(拼写错误也会报该错误)
b、字段不匹配:
传递到dao的实体中的字段,与mybatis中sql语句不匹配,缺少对应的列,对比检查;
20、token管理机制:
(1)当用户第一次登录后,服务器生成一个token并将此token返回给客户端,客户端保存,发
送请求时带上这个token;服务器验证token,并生成新的token2保存并发给客户端,客户端保存,
发送请求时带上这个token2......
(2)当发客户端发送多个请求,服务器响应请求1验证token1,并生成新的token2时,
请求2正携带token1请求服务器,这样会出错。故可以为token设置一个有效期。
21、接口的存在是用来解耦的。微服务中,一个微服务是最小的开发单元了,所以不需要接口了吗?
不,微服务是会互相调用的,所以应该把实体类以及会被调用的接口等,单独的放在一个模块中,然后自己的模块引入该模块的依赖,这样的话,如果该微服务需要被调用,那么使用feign,然后只需要引入这个基础模块的依赖即可,不用重复的写实体类以及对应的接口了。
22、微服务开发的流程?
我们需要把搭建成服务的功能做成镜像,再把镜像做成容器;
微服务是同类容器的集合。
23、SpringBootApplication 注解?
@SpringBootApplication =
@Configuration + @EnableAutoConfiguration + @ComponentScan;
-
@Configuration:提到@Configuration就要提到他的搭档@Bean。使用这两个注解就可以创建一个简单的spring配置类,可以用来替代相应的xml配置文件。
@Configuration的注解类标识这个类可以使用Spring IoC容器作为bean定义的来源。@Bean注解告诉Spring,一个带有@Bean的注解方法将返回一个对象,该对象应该被注册为在Spring应用程序上下文中的bean。
- @EnableAutoConfiguration:能够自动配置spring的上下文,试图猜测和配置你想要的bean类,通常会自动根据你的类路径和你的bean定义自动配置。
-
@ComponentScan:会自动扫描指定包下的全部标有@Component的类,并注册成bean,当然包括@Component下的子注解@Service,@Repository,@Controller。
也就是说,如果加了这个注解,就不用加@Bean注解了,直接可以通过@Autowired注入;
24、深入解释@Configuration?
@Configuration
public class BookStoreDaoConfig{
@Bean
public UserDao userDao(){ return new UserDaoImpl();}
@Bean
public BookDao bookDao(){return new BookDaoImpl();}
}
Spring 在解析到以上文件时,将识别出标注 @Bean 的所有方法,执行之,并将方法的返回值 ( 这里是 UserDaoImpl 和 BookDaoImpl 对象 ) 注册到 IoC 容器中。默认情况下,Bean 的名字即为方法名(与配置根据名称注入/类型注入有关?);
Spring 可以识别所有标记了 @Component、@Controller、@Service、@Repository 注解的类,由于 @Configuration 注解本身也用 @Component 标注了,Spring 将能够识别出 @Configuration 标注类并正确解析之;
25、启动web项目的时候,如果ServletContext找不到的话,手动把servlet的jar放到lib下,或者maven项目加依赖,设置scope为编译时有效;
26、把指定目录下的jar文件安装到maven仓库中?
mvn install:install-file -Dfile=D:\jar\aliyun-java-sdk-core-3.2.5.jar -DgroupId=com.aliyun -DartifactId=aliyun-java-sdk-core -Dversion=3.2.5 -Dpackaging=jar
有的jar是需要收费的(oracle),所以maven不会帮我们自动下载,需要我们自己手动安装到maven仓库中;
27、注解标识根据名称/类型注入对象到spring容器?
@Autowired 根据类型注入;
@Resource 默认根据名字注入,其次按照类型搜索;
-
@Autowired @Qualifie(“userService”) 两个结合起来可以根据名字和类型注入
@Autowired(required=true)
一定要找到匹配的Bean,否则抛异常。 默认值就是true
@Autowired
@Qualifier(“bean的名字”)
按名称装配Bean,与@Autowired组合使用,解决按类型匹配找到多个Bean问题。
-
@Resource(name=“cusInfoService”)
默认按name注入,可以通过name和type属性进行选择性注入;
当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
28、mongodb的使用?
启动服务:mongod --dbpath d:\dbData
新建一个窗口执行mongo,连接上服务,默认ip为本地;
29、使用注解标识开启事务失效的情况?
@Transactional 注解应该只被应用到 public 可见度的方法上。
如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置。
30、map的大小为什么能保持是2的次幂?map相关重点?
- 手动new一个map,初始为5的话,底层会进行位移运算,人为传参与n(n本身是1)比较,n小于5就左移,直到大于5,所以结果是8;
- 如果需要保证线程安全,那么可以对map使用synchronized包装;
- 放在哪个桶是通过hash函数计算的(然后又取余了), 桶的个数变了,位置都需要重新计算,也就是说位置与总数有关系;
- 加载因子是折中的,最好的情况是不产生碰撞,查询效率高;
31、关于tomcat使用过程中遇到的一些问题?
- Tomcat 设置URI默认字符集为UTF-8可以解决请求路径参数中文乱码;
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
- Tomcat修改端口的话一下子需要改三个(adminPort、http请求的port、ajp请求的port);
- 有时候即使修改了eclipse工作空间对应配置的tomcat的配置文件中的端口,项目中可能也不会生效,因为他用的eclipse自带的tomcat,这样的话,可以在开发工具中双击server进行端口的修改,以及文件部署位置的修改;
32、驾驶舱数据联动,滚屏方法只需要调用一次就会保持滚动,联动只需要数据刷新即可;设置标志位,使之只调用一次;另外方法可能是自己写的,不是封装好的;
33、泛型的使用?
如果声明hashmap的时候不指定泛型,会有警告信息,所以注意一下黄线;
34、枚举是具有固定实例个数的类?是单例吗?
35、小技巧
- 模糊,隐藏图标,修改分辨率,就更加清晰;
- maven中央仓库可以直接下载jar包;
- 可以从层级视图那里排除一些传递依赖;
- pom类型的项目可以作为父项目来管理依赖;
- properties可以统一管理版本号,这样修改的话,一并修改了,不用单独去下面挨个的找;
- 右键maven-mavenUpdate可以更新maven项目,有问题的时候可以这样做;
- wifi共享大师;