一 WEB JAVA知识学习
1 JSON web tokens 身份认证 rest webservice的几种方式
a: base64: username
b: 保存shiro里的sessionId, 每次都要回传,有session共享问题(如果服务器部署集群的话)
c: jwt,每次都传 固定的 json,无状态的,支持集群 http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
2 验证码自动生成总结
a;本质是个servlet,配置要写在web.xml里
b: 点击刷新功能是 οnclick='this.src='xxxxxx.do'+Math.random();' 记得去掉容易混淆字体
c:随机刷新的原理和后台无关,怕是浏览器缓存造成不刷新,需要使用googole的插件maven,可生成颜色,
位置,背景噪音横条等
<img id="verificationcode" title="Click the refresh" src="xzzzzzzzzzimagecode?rnd=0.5650006300705059" width="116" height="36" οnclick="this.src = 'http://aaaaaaaa/imagecode?rnd=' + Math.random(); ">
3 单点登录的设计思路:
如果不同则是 在其他设备登录,如果没有则是账号过期,放在拦截器中处理,如果 需要实时的通知需要透传,极光推送的自定义消息(手机端程序)
4 spring 进行表单验证 @Valid
使用基于xxx标准的注解方式 用到了c3p0,jboss等jar包,步骤是:
a: 使用Pojo类引入注解 Max Min, Size,Email, DecimalMax,DecimalMin xxxxxx
b: 主类中 @Validated pojo, BindingResult result xxxxx ,错误数据保存,需要刷新(有两种方式类,另外一种是@valid Errors类,目前项目用来BindingResult),其中BindingResult 实现类Errors的方法
c :页面展示, 重新跳转到form页,然后显示了错误信息,结合bootstrap的类,点一下后就会消失
5 使用验证器验证表单, InitBinder,第二功能:类型转换
验证器参考 databinder.setValidate(aaa class extends validator (实现validate方法,例如价格比较等逻辑验证))
第二个功能:类型转换,自动转换时间的格式,int,double等,参考文章 https://www.cnblogs.com/heyonggang/p/6186633.html
6 删除带外键的基础数据方法
删除带外键的基础数据方式是先查询时候有外键数据有则删除,最后删基础数据 其中delete的no action意思是删数据的时候不自动删被依赖的数据,需要手动删除
7 spring boot路径父路径错误问题原因
spring boot 这样用法不可行的原因
返回类当前路径的方法:当前路径都是classes层的下一层
path = new File(BlackmanService.class.getResource("/").getPath()).getParentFile().getParentFile().getParentFile().getCanonicalPath();
查看路径可知 路径竟然是jar包路径,当然路径不正确了, springboot和 tomcat项目完全不同,tomcat的会解压生成class而springboot则不会
file:/D:/workspaces_myeclipseci3/middleman/target/middleman-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/
java.io.IOException: 文件名、目录名或卷标语法不正确。
at java.io.WinNTFileSystem.canonicalize0(Native Method)
8 springboot打包运行部署的方法
添加一个插件,可以在外面配置配置文件可以修改
<!-- usage: mvn package spring-boot:repackage -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<mainClass>com.stelect.monitor.MonitorStart</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
9验证数据的思路,需要去刷新页面
添加一个验证,验证修改总数,有错误会加上model.asMap.add,如果数量不等表示有错,
如何判断是否修改,调接口,再查数据库如果值不同则设置名字有例如map.put(key,has),
验证完了就判断map如果有就说明需要修改至或者调用
10 多线程数据的问题,不一定需要 等待,因为是多线程,才加,单线程不需要的
package com.hbean.btlcloud.webservice;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class TestG {
public static void main(String[] args) {
restThread restThread = new restThread();
ResponseBean responseBean = new ResponseBean();
ExecutorService executor = Executors.newCachedThreadPool();
try {
Future<ResponseBean> future = executor.submit(restThread);
System.out.println(future.get().name);
Thread.sleep(1000);
// executor.shutdown();
// executor.awaitTermination(10, TimeUnit.SECONDS);
}
catch (Exception e) {
}
}
}
class ResponseBean{
int name;
ResponseBean(){}
ResponseBean(int name){this.name=name;}
}
class restThread implements Callable<ResponseBean>{
@Override
public ResponseBean call() throws Exception {
Thread.sleep(3000);
return new ResponseBean(123);
}
}
11 myeclipse ci3 破解的方法
网上教程太多,都是正确的,老是错误是因为破解的 工具有问题,用下面的链接可以正确破解,亲测可用
https://download.csdn.net/download/u014017819/9763883
12进入初始化也和初始化数据写法技巧
初始化登录页面用GET, 进行登录用POST,这样就可以用同名的函数了,不会不好起名字
13 获取当前请求路径
最常用的 反倒是最好用的
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
14 如何理解<base href="<%=basePath%>"
参考文章:用于保存相对路径的,有了他就不需要别的路径了,只能放在header里面且不渲染
https://blog.csdn.net/johnstrive/article/details/37805463
15 暴力获取 webcontext spring上下文的方法
WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
UserAccountService userAccountService = (UserAccountService)wac.getBean("userAccountService");
18 使用group by语句里的having 条件 切记 需要group by 里面排序过,否则返回的都是空
17拦截器过滤 spring 使用 MethodInterceptor
可以拦截方法同时返回需要的参数类型 ,不可用注入但是可以自动注入 httpserveltrequest
19 Memcache的用法
1 telnet localhost 11211 telnet连接mem
2 get xxxx 获取值
3 stats 查询状态
参数介绍
1、 以上的安装和启动都是在默认环境下进行的,在安装时可设置如下参数:
-p 监听的端口
-l 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u 以的身份运行 (仅在以root运行的时候有效)
-m 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时连接数,默认是1024
-f 块大小增长因子,默认是1.25
-n 最小分配空间,key+value+flags默认是48
-h 显示帮助
如:“memcached -d install -l 127.0.0.1 -m 1024 -c2048”。
https://github.com/memcached/memcached/wiki文档
21 three js
https://github.com/josdirksen/learning-threejs
22 图片
background-color:rgba(0,0,0,0.6) 半透明背景
color :rgba(255,255,255)
22 spring boot 部署为旧的war 的方法
1)启动类继承 extends SpringBootServletInitializer,实现默认configure方法
2) 改包为war类型
3) 添加pom的tomcat依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
来源官网 85.1 章节:
23 jquery一些函数
xxx.toArray() 转为 dom数组
xxx.index(dom) 反查 索引号
add(xxx)添加附加同类型的 数据
24 Docker安装和安装tomcat
查看centos内核版本
uname -r
教程:
安装两种方式 yum和 脚本很清楚
安装步骤
http://www.runoob.com/docker/centos-docker-install.html
安装tomcat,启动成功但是无法访问
http://www.runoob.com/docker/docker-install-tomcat.html
docker run --name tomcat5 -p 8081:8081 -v $PWD/test:/usr/local/tomcat/webapps/test -d tomcat
进不去需要启动 里面程序才可以,光启动tomcat的image不管用
例如 docker exec -it tomcat5 bin/sh
浏览器访问必须是 ip地址 用ifocnig -a已经无法查看,而且tomcat的默认地址就是8080,哪怕外面的
映射都是为8081,都不是设置tomcat端口的
25 返回当前时间到第二天凌晨剩余秒数,存于memcache中,因为发消息需要每天只发一次
public static Long getSecondsNextEarlyMorning() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_YEAR, 1);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.MILLISECOND, 0);
Long seconds = (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
return seconds.longValue();
}
26 shiro 学习
shiro高级学习网站
https://www.w3cschool.cn/shiro/8tnc1if9.html
授权身份
oauth2 使用证书??? http://oauth.net/2/
日期的自动映射问题
shiro支持 ssl 就是 https ,需要配置证书,指定tomcat的证书路径,和密码同证书相同,默认8443
然后配置shiro的配置文件即可
session依赖于cookie,cookie如果设置了有效期,则打开同以页面则cookie不删除
spring处理异常 方法
@ExceptionHandler({UnauthorizedException.class})
shiro的rember me 和授权二选一
26_2 shiro搭建步骤
shiro分几个功能模块,完全相互独立一点一点来
第一是 拦截功能实现
添加web,添加shiro.xml, 添加 realm重写的,如果需要动态获取总拦截则要重写 shiroFilter,里面重写setfilterChainDefinitions 方法,
高级功能
第二是登录后权限的赋值和验证
在realm里面可以自己实现 AuthenticatingRealm 里面的属性 credentialsMatcher,重写匹配器,如果不写就会使用默认的验证密码问题
第三是 共享公共单点登录问题 自动修改权限问题 (高级功能)
1 负责拦截器的拦截,如果失败跳转到某一个地方
2 单独的拦截器
3 realm 一个新建user,从数据库查,一个给user授权
AuthenticatingRealm 多级继承问题
27 oauth2 实例代码
https://github.com/favccxx/FavOAuth2
oauth流程
1 四个角色, client申请获取申请权限,资源服务器返回同意,
2 client用申请权限 从验证权限获取tokenaccess,认证服务器返回token
3 client根据token 获取资源
28 Game2.5d设计思路
1 背景图 透明度慢慢变100,刚进入时
2 强关联,弱分类,人物图片规则是使用 序号,不写死名字,路径全用静态变量代替,后台有javaweb
3 先开放限制
29 配置阿里的镜像 maven,解决了 jar包找不到的问题
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>
http://maven.aliyun.com/nexus/content/groups/public/
</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
offline 默认是false,就是说联网的时候就下载,不用改
proxy 就是代理服务器,为何用代理,第一是过滤,第二节省ip点
service 如果建立了私服会这样来用的
30 kafka
保证插入mysql数据一致性,需要保存 插入数据和调用数据返回结果 放于同一事务中
31 RequestContextListener 监听器的作用
这个监听器添加了 bean的 三个作用域 session. globalsessioni,request
32 搭建spring mvc的 小白搭建方法
https://www.cnblogs.com/xing901022/p/5240044.html
加上requestcontextlistener为了支持bean、的三个作用域 request,sessionxxx
servelt的mvc必须配置 psring-mvc.xml,重了也没有关系,没有的话会找默认的配置,估计会没有,不加前后缀的将要 配置 controller用 responsebody,就好返回直接
的字符串,类似于ajax返回值,否则是相当于跳转,没页面就会没空
搭建很简单,先manven的web,加载jar包,复制三大块在web.xml,配置两个xml,里面有扫描包和 试图解析器,然后 写页面和controller即可
33 mysql 只导出表结构的方法
mysqldump -h192.168.100.990 -uroot -pmypwd -d dbname>dbnamedd.sql
34 Git常用方法总结
git经常失败原因是要一点一点来,先普通git再用eclipse,
添加新工程用建立本地local仓库时,会把本地程序移到仓库里,新加的文件要加 add index
添加远程仓库需要本地仓库初始化,需要用git,不然各种错误,还是原理初始的不了解,
使用
git init
git remote add origin https://gitee.com/supergood/xiaochong.git
git branch -r
然后先拉取再提交等等
还有配置的时候有 添加 user.name xxx, user.email xxx@email ,密码是远程提交时才加 的
二 微信小程序,公众号开发
1 获取权限流程
a: 客户申请(类似于小程序弹出页面需要被授权),b 用户同意(返回code,)c,客户(类似于小程序服务器)用code换token
d: 客户(类似于小程序服务器)根据token 获取用户基本信息很多, [中间有刷新token的功能,为了延长获取时间,例如默认是2小时]
三:NOI NETTY模块
1 做netty登录逻辑:
a:先做登录为了安全,服务端根据 登录的参数ip和 chanel的ip判断如相同则登录成功,做登录是实现了ChannelInboundHandlerAdapter类,的方法,在激活的方法channelActive里,初始化全局变量ChannelHandlerContext,用于写数据给server
b:成功后 开启定时任务写数据,其中用到了全局变量,继续写任务,如果server判断了未登录则进行登录,操作都是在channelRead方法中进行
c:还集成了 channelInactive exceptionCaught接口以做备用
2 Netty的数字传输分包粘包问题解决,客户端不需要修改,只需要加上结尾符, 服务端使用
pipeline.addLast(new DelimiterBasedFrameDecoder(Delimiter_length, delimiter));
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());
客户端用心跳只用普通的即可
new IdleStateHandler(20, 0, 0, TimeUnit.SECONDS),
idleStateTrigger,
new StringDecoder(),
new StringEncoder(),
3 Netty 客户端服务端重连机制理解
四 Dubbo 模块
1 helloworld 需要5个步骤,记得端口ip有范围 224-239
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
public interface GreetingService {
String sayHello(String name);
}
import org.apache.dubbo.demo.GreetingService;
public class GreetingServiceImpl implements GreetingService {
public String sayHello(String name) {
return "Hello " + name;
}
}
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;
import org.apache.dubbo.demo.GreetingService;
import java.io.IOException;
public class Provider {
public static void main(String[] args) throws IOException {
ServiceConfig<GreetingService> serviceConfig = new ServiceConfig<GreetingService>();
serviceConfig.setApplication(new ApplicationConfig("first-dubbo-provider"));
serviceConfig.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234"));
serviceConfig.setInterface(GreetingService.class);
serviceConfig.setRef(new GreetingServiceImpl());
serviceConfig.export();
System.in.read();
}
}
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import org.apache.dubbo.demo.GreetingService;
public class Consumer {
public static void main(String[] args) {
ReferenceConfig<GreetingService> referenceConfig = new ReferenceConfig<GreetingService>();
referenceConfig.setApplication(new ApplicationConfig("first-dubbo-consumer"));
referenceConfig.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234"));
referenceConfig.setInterface(GreetingService.class);
GreetingService greetingService = referenceConfig.get();
System.out.println(greetingService.sayHello("world"));
}
}
23 daterangepicker 插件作用是范围内是时间值input
需要引入3个文件和1个js
<link rel="stylesheet" type="text/css" href="<%=basePath %>Scripts/daterangepicker/daterangepicker.css">
<script type="text/javascript" src="<%=basePath %>Scripts/daterangepicker/moment.min.js"></script>
<script type="text/javascript" src="<%=basePath %>Scripts/daterangepicker/daterangepicker.js"></script>
// 初始化时间控件
$("#fromDateId,#toDateId").daterangepicker({
"locale": {
"format": "YYYY-MM-DD HH:mm:ss"
},
"timePicker": true,
"timePicker24Hour": true,
"setlanguage": "zh-cn",
"timePickerSeconds": true,
"showClearBtn": true,//是否显示清空按钮
singleDatePicker: true,
showDropdowns:true
}, function (start, end, label) {
});
24 js引入el和使用el数据方法,jsp默认开启了el表达式
var abc = ${abc};
25用jquery.pager实现分页
成熟的解决方案
https://github.com/jonpauldavies/jquery-pager-plugin
26 maven 搭建web项目方法
新建 maven工程, 过滤的时候填写 webapp 选中完成 运行即可
27 shiro动态更新权限有两个场景
因为存在了 realm和 factorybean,需要更新这两个
factorybean是个基础的 权限,在shirofilter里面,基础权限修改就是重新设置filter拦截器作为原理
ServletContext servletContext = request.getServletContext();
WebApplicationContext webAppContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
ShiroPermissionFactory shiroPermissionFactory = (ShiroPermissionFactory)BeanFactoryUtils.beanOfTypeIncludingAncestors(webAppContext, ShiroPermissionFactory.class);
shiroPermissionFactory.setFilterChainDefinitions(ShiroPermissionFactory.definitions);
另外一个是 realm,这个权限针对于 的是具体用户权限变更,动态修改用户权限就是先删除掉所有的权限,然后程序一看没有则自动调用realm验证达到了 动态修改权限的目的
User user = userDao.getUserById(userId);
RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
CustomRealm shiroRealm = (CustomRealm)rsm.getRealms().iterator().next();
Subject subject = SecurityUtils.getSubject();
String realmName = subject.getPrincipals().getRealmNames().iterator().next();
SimplePrincipalCollection principals = new SimplePrincipalCollection(user.getUserName(), realmName);
if (shiroRealm.getAuthorizationCache().get(principals) != null) {
shiroRealm.getAuthorizationCache().remove(principals);
subject.releaseRunAs();
}
五 Spring boot的学习
1 异常全局处理和配置
@ControllerAdvice 用于全局配置,例如配置 统一一场处理信息
配合@ExceptionHandler即可
2 日志配置,默认有四种 logback,log4j,log4j2,Logging
配置log目录
logging.file=d:/abc.log
配置日志级别
logging.level.org.springframework.web=DEBUG
六 大数据相关技术
1 常见的 优化:
太高的TPS放于缓存中,用于读取db
插入数据不会慢,因为是顺序执行,查询会慢,当大雨500万行的时候(需要垂直分表)
水平拆分表就是 大表拆分为小表
2 集群和分布式区别,集群是多个相同系统,分布式是 一个系统分布各自的模块分布到 不同的机器上
3 分表中间件 mycat,cobar,tddl
七 面试总结
1 Hahmap的理解
类型 | 添加 | 删除 | 查找 |
|
数组 | N | n | 1(下标)/n(值)/高效为logn |
|
Hash | 1 | 1 | 1(主干为数组) |
|
先通过哈希函数计算出实际存储地址,然后从数组中对应地址取出即可,数组和链地址法,
数组+链表 的方法
构造函数两个值,一个是加载银子,填充程度,太高了,影响查询效率,但有空间利用率,一个是 xxxx
2 死锁原因和条件
死锁是 多个进程有持有自己的资源同时申请别人的资源,进入循环等待状态,四个条件,都不是共享资源,都不可剥夺
都进行对方申请循环等待,都进入了循环状态
3 hessian
二进制协议,多个客户端写的,高效不必学习其他巨大协议
4 Java虚拟机类加载流程和常用 虚拟机命令
jps 模仿 unix的命令ps 功能也类似,是查看虚拟机所有进程
jstat -gcutil 3222
suvivor0 suvivor1 eden O P YGC YGCT FGC FGCT GCT
幸存者(from),幸存者To 伊甸园就是类刚被加载进来存放的地方,gc回收后清空,幸存者两个有一个必为空,可以相互转化,O老年代,P持久带,都是百分比,
YGC minor gc次数,耗时,全gc次数,耗时,总的 GC回收时间包含前面两个
类加载的流程
从字节码转为机器码可能是
类的编译--加载--连接(验证(),准备,解析)--初始化(真正的给静态变量赋值)
五:面试题汇总
session共享机制:
1 共享保存的文件目录
2 使用memcache保存,因为有过期机制
dubbo 面试
常见协议:dubbo,采用三个集成mina,hessian(用于序列话),nio单连接场链接,不适合大文件传输
hessian和上面相反,短链接,多连接,可以传文件
注册中心:
zookeeper,multiple,redis