2018.03
以下大部分是面试中遇到的,做个总结,如果有哪不好,还望各位指出。
//什么是面向对象
将现实世界的事物抽象出来,映射到程序中,具有相似属性和行为的对象属于一类,通过程序模拟对象之间的行为
面向对象从另一个角度来解决这个问题。它抛弃了函数,把「对象」作为程序的基本单元。那么对象到底是个什么东西呢?对象就是对事物的一种抽象描述。
我们创建的对象,应该是刚刚好能做完它能做的事情,不多做,不少做。多做了容易耦合,各种功能杂糅在一个对象里。
继承就是决定该对象的属性、方法可以被哪个对象使用
把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象。对同类对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。程序流程由用户在使用中决定。
面向对象的本质就是让对象有多态性,把不同对象以同一特性来归组,统一处理。
你并不知道我是怎么做到的。你不知道哪里有洗衣店,也可能只会说法语,或者是兜里没钱,连车都打不了。但是我知道怎么完成这项任务,而你不需要知道任何细节。所有的这些复杂流程都隐藏在我的内部,而我们之间可以高度抽象地互动。这就是对象。他们把复杂过程封装在内部,而对外呈现的接口是高层次的,抽象的。
一、sql
查看当前时间
mysql SELECT NOW();
oracle select sysdate from dual;
获取mysql的当前插入的id
select last_insert_id(); max(id)
oracle引擎 oracle中不存在引擎的概念,数据处理大致可以分成两大类:联机事务处理OLTP(on-line transaction processing)、联机分析处理OLAP(On-Line Analytical Processing)。
OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易。OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。
MySQL是一个关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
innodb
提供事务处理
支持外键约束
InnoDB表按照主键的顺序组织存放在磁盘上(索引组织表),优化基于主键的查询
支持全文索引 从MySQL 5.6.4开始
支持行级锁
CPU 利用率是其他所有基于磁盘的关系数据库引擎中最有效率的。
索引存放在表空间里面
myisam
MyISAM强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持
系统奔溃后,MyISAM恢复起来更困难
sql失效的情况
where条件出来的数据太多,大于15%,使得索引失效
对索引列进行运算导致索引失效,我所指的对索引列进行运算包括(+,-,*,/,! 等) 对字段进行表达式操作 函数操作
在=左边进行,函数、算术运算或其他表达式运算
如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误. varchar2(20),查询时把该字段作为number类型
单独引用复合索引里非第一位置的索引列.
B-tree索引 is null不会走,is not null会走,位图索引 is null,is not null 都会走 索引
索引是有序的。NULL值进入索引时,无法确定其应该放在哪里。
应尽量避免在 where 子句中使用!=或<>操作符
尽量避免在 where 子句中使用 or 来连接条件
要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引
in 和 not in 也要慎用 用 exists 代替 in
在 where 子句中使用参数
索引列有大量数据重复时
like查询以%开头
如果mysql估计使用全表扫描要比使用索引快,则不使用索引
对小表查询
强制查询使用索引:
select id from t with(index(索引名)) where num=@num
MySQL主要提供2种方式的索引:B-Tree索引,Hash索引 hash高效,限制多
where执行顺序 mysql 从左到右,oracle从右到左。
优化
表 索引 sql语句
尽量避免大事务操作,提高系统并发能力。
TINYINT(size) -128 到 127 常规。0 到 255 无符号*。
$引起sql注入,${}会直接参与sql编译。会影响sql语句的预编译。
$方式一般用于传入数据库对象,例如传入表名.
order by ${}
$符是直接拼成sql的 ,#符则会以字符串的形式 与sql进行拼接。
二、spring
轻量级的开源容器框架
目标是简化Java企业级应用开发
核心是控制反转(IoC)和面向切面(AOP)。
特点
配置文件集中配置系统
方便解耦,简化开发 对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。
AOP编程的支持
声明式事务的支持
方便集成各种优秀框架
降低Java EE API的使用难度 封装了很多api
ioc最重要的一点就是在程序运行的时候可以动态的向某个对象提供所它依赖对象的实例。
IOC是解耦,提供一种构造对象的方式,使得一种功能能有多种实现,且不构成依赖。spring 的IOC的缺点:占用内存多、构造对象慢、启动慢。
1.低侵入式设计,代码污染极低
2.独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺
3.Spring的DI机制降低了业务对象替换的复杂性,提高了组件之间的解耦
4.Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用
5.Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问
6.Spring并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部
框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件
SpringMVC流程
1、 用户向服务器发送请求,请求被SpringMVC的前端控制器DispatcherServlet截获。
2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给
DispatcherServlet。
4、 DispatcherServlet调用HandlerAdapter处理器适配器。
5、 HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、 Controller执行完成返回ModelAndView。
7、 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8、 DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9、 ViewReslover解析后返回具体View。
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、 DispatcherServlet响应用户。
三、web
jsp
jsp如何获得html form中的数据
action="myjsp.jsp"
name="data"
<% request.getParmerter("data");%>获取html页面传递过来的数据
解决乱码
<% request.setCharacterEncoding("GB2312");
request.setCharacterEncoding("GB2312"); %>
jsp调用java类
<%@page import="java.util.ArrayList"%>
九大内置对象
内置对象名 类型
request HttpServletRequest
response HttpServletResponse
config ServletConfig
application ServletContext
session HttpSession
exception Throwable
page Object(this)
out JspWriter
pageContext PageContext
ajax
jquery中ajax方法有个属性async用于控制同步和异步,默认是true,即ajax请求默认是异步请求,有时项目中会用到AJAX同步。这个同步的意思是当JS代码加载到当前AJAX的时候会把页面里所有的代码停止加载,页面出现假死状态,当这个AJAX执行完毕后才会继续运行其他代码页面假死状态解除。而异步则这个AJAX代码运行中的时候其他代码一样可以运行。
ajax中async这个属性,用于控制请求数据的方式,默认是true,即默认以异步的方式请求数据。
四、redis
Redis 是完全开源免费的,遵守BSD协议,基于内存,是一个高性能的key-value数据库。
性能极高
丰富的数据类型
原子性
优点
(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
(2) 支持丰富数据类型,支持string,list,set,sorted set,hash
(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除
redis的速度比memcached快很多
redis数据可以持久化存储,即使服务重启之后,redis缓存的数据也不会丢失。
Redis的回收策略
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据
五、bootstrap
Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架。
它是一种前端框架,用来优化前端界面的。提供优雅的HTML和CSS规范,能够响应式布局,兼容PC端及手机端。
Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷。
移动设备优先,支持主流浏览器,易使用,响应式设计
快速开发,节省时间,不再浪费时间写脚本
提供全面的组件
内置Jquery插件
缺点
必须在同一系统中使用两套css预处理框架来做相同的事。(less、sass)
css框架对于一个小项目等页面来说很臃肿。框架中可能有大部分你用不到的代码。
太依赖框架,以至于很难排除bug。包括框架中本身就带的bug。
选择自己需要的框架与开发框架都很痛苦。写到后面发现越来越不灵活,越来越臃肿。
加载速度慢
六、多线程
创建两个线程,一个增,一个减
public class Test {
// Runnable 线程可以共享实例属性
private int i = 0;
private synchronized void add() {
i++;
System.out.println(Thread.currentThread().getName() + "--add:" + i);
}
private synchronized void dec() {
i--;
System.out.println(Thread.currentThread().getName() + "--dec:" + i);
}
class Add implements Runnable {
public void run() {
add();
}
}
class Dec implements Runnable {
public void run() {
dec();
}
}
public static void main(String[] args) {
Test t = new Test();
Add add = t.new Add();
Dec dec = t.new Dec();
for (int i = 0; i < 1000; i++) {
new Thread(add).start();
new Thread(dec).start();
}
}
}
七、算法
斐波那契数列
public static int fibonac1(int n) {
if (n == 0)
return 0;
if (n == 1)
return 1;
return fibonac1(n - 1) + fibonac1(n - 2);
}
/**优化
* @param a 1
* @param b 1
*/
public static int fibonac2(int a, int b, int n) {
if (n > 2)
return fibonac2(a + b, a, n - 1);
return a;
}
约瑟夫环
/**0,1,...,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求这个圆圈里剩下的最后一个数字。
* 一个递归的公示。要得到n个数字的序列中最后剩下的数字,只需要得到n-1个数字的序列和最后剩下的数字,并以此类推。
* f[n]=(f[n-1]+k)%n
* f[2]=(f[1]+k)%2
* f[3]=(f[2]+k)%3
* @param n
* @param m
* @return
*/
public static int lastRemaining(int n, int m){
if(n < 1 || m < 1)
return -1;
int last = 0;
for(int i = 2; i <= n; i++)
last = (last + m) % i;
return last;
}
八皇后
public class Empress8 {
public static void main(String[] args) {
Empress a = new Empress();
a.find(0);
System.out.println("八皇后问题共有:" + a.num + "种可能");
}
}
class Empress {
public int[][] arr = new int[8][8]; // 棋盘,放皇后
public int num = 0; // 存储方案结果
public boolean check(int arr[][], int k, int j) { // 判断节点是否合适
for (int i = 0; i < 8; i++) { // 列冲突
if (arr[i][j] == 1)
return false;
}
for (int i = k - 1, m = j - 1; i >= 0 && m >= 0; i--, m--) { // 左前对角线
if (arr[i][m] == 1)
return false;
}
for (int i = k - 1, m = j + 1; i >= 0 && m <= 7; i--, m++) { // 右前对角线
if (arr[i][m] == 1)
return false;
}
return true;
}
/**回溯过程中已舍弃的皇后代表的数组元素要置0,以免接下来继续使用深度优先搜索时,使用判断规则
* public boolean check(int arr[][],int k,int j){}出现判断错误。
* @param i
*/
public void find(int i) { // 寻找皇后节点
if (i > 7) { // 八皇后解
num++;
print();
return;
}
for (int m = 0; m < 8; m++) { // 深度优先,递归算法
if (check(arr, i, m)) {
arr[i][m] = 1;
find(i + 1);
arr[i][m] = 0;
}
}
}
public void print() { // 打印方法结果
for (int[] i : arr) {
for (int j : i) {
System.out.print(j + " ");
}
System.out.println();
}
System.out.println(num);
}
}
用两个栈实现一个队列
public class StackQueue {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if (stack1.empty() && stack2.empty()) {
throw new RuntimeException("Queue is empty!");
}
if (stack2.empty()) {
while (!stack1.empty()) {
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
}
顺时针打印矩阵
public void printMatrixInCircle(int[][] array){
if(array == null)
return;
int start = 0;
while(array[0].length > start*2 && array.length >start*2){
printOneCircle(array,start);
start++;
}
}
private void printOneCircle(int[][] array,int start){
int columns = array[0].length;
int rows = array.length;
int endX = columns - 1 - start;
int endY = rows - 1 - start;
//从左到右打印一行
for(int i = start;i <= endX ;i++){
int number = array[start][i];
System.out.print(number+",");
}
//从上到下打印一列
if(start <endY){
for(int i = start +1;i<=endY;i++){
int number = array[i][endX];
System.out.print(number+",");
}
}
//从右到左打印一行
if(start < endX && start < endY){
for(int i = endX -1;i>=start;i--){
int number = array[endY][i];
System.out.print(number+",");
}
}
//从下到上打印一列
if(start <endY && start <endY -1){
for(int i =endY -1;i>=start+1;i--){
int number = array[i][start];
System.out.print(number+",");
}
}
}
给你字符串 s 和整数 k 。
请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。
英文中的 元音字母 为(a, e, i, o, u)。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-number-of-vowels-in-a-substring-of-given-length
//滑动窗口
class Solution {
public int maxVowels(String s, int k) {
int left = 0;
int right = 0;
int max = 0;
int count = 0;
while(right<s.length()){
char temp = s.charAt(right);
if(temp=='a'||temp=='e'||temp=='i'||temp=='o'||temp=='u'){
count++;
}
right++;
if (right-left==k){
max = Math.max(max,count);
char c = s.charAt(left);
if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'){
count--;
}
left++;
}
}
return max;
}
}
//集合类
class Solution {
public int maxVowels(String s, int k) {
Set<Character> set = new HashSet();
set.add('a');
set.add('e');
set.add('i');
set.add('o');
set.add('u');
int r = 0, cur = 0;
for (r = 0; r < k; r++) {
if (r >= s.length()) return cur;
if (set.contains(s.charAt(r))) cur++;
}
int l = 0, max = cur;
while (r < s.length()) {
if (set.contains(s.charAt(l++))) cur--;
if (set.contains(s.charAt(r++))) cur++;
max = Math.max(max, cur);
}
return max;
}
}
//前缀和
class Solution {
public int maxVowels(String s, int k) {
int n = s.length();
int maxLen = 0;
int[] prefixSum = new int[n + 1];
for (int i = 1; i < n + 1; i++) {
prefixSum[i] = prefixSum[i - 1] + (isVowel(s.charAt(i - 1)) ? 1 : 0);
}
for (int i = 0; i < n - k + 1; i++) {
maxLen = Math.max(maxLen, prefixSum[i + k] - prefixSum[i]);
}
return maxLen;
}
private boolean isVowel(char c) {
return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}
}
八、biz
购物车 订单
购物车表
订单表 支付情况 物流情况
订单详情表
九、shiro
用户表
角色表
权限表
用户角色表
角色权限表
十、JSON-RPC
JSON-RPC是一种基于JSON的跨语言远程调用协议。有文本传输数据小,便于调试扩展的特点。
十一、linux
ps -ef|grep
ps命令将某个进程显示出来
grep命令是查找
中间的|是管道命令 是指ps命令与grep同时执行
PS是LINUX下最常用的也是非常强大的进程查看命令
grep命令是查找,是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。
以下这条命令是检查java 进程是否存在:ps -ef |grep java
other
Java中用来处理Excel的第三方开源项目主要就是POI和JXL。poi功能强大,但是比较耗资源,对于大数据量的导入导出性能不是太好;jxl功能简单,但是性能比较好。
filter
Jsp,Servlet, 静态图片文件或静态html文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等
filter的doFilter方法
Listener
Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要作用是: 做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。