面试问题

Posted mrneng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试问题相关的知识,希望对你有一定的参考价值。

1、 pageHelper分页插件的使用

Mybatisplugin实现了Interceptor接口,可以在插件中获得执行的sql语句,sql语句中添加limit语句实现分页。

使用原理:pageHelper会使用ThreadLocal获取同一线程中的变量信息,各个线程之间的Threadlocal不会相互干扰,也就是Thread1中的ThreadLocal1之后获取到Tread1中的变量的信息,不会获取到Thread2中的信息所以在多线程环境下,各个Threadlocal之间相互隔离,可以实现,不同thread使用不同的数据源或不同的Thread中执行不同的SQL语句

所以,PageHelper利用这一点通过拦截器获取到同一线程中的预编译好的SQL语句之后将SQL语句包装成具有分页功能的SQL语句,并将其再次赋值给下一步操作,所以实际执行的SQL语句就是有了分页功能的SQL语句

2、 防止Sql注入

1) Sql注入攻击的总体思路

1、 寻找SQL注入的位置

2、 判断服务器类型和后台数据库类型

3、 针对不通的服务器和数据库特点进行SQL注入攻击

   方法:

1PreparedStatement

采用预编译语句集,内置了处理sql注入的能力,只要使用它的setXXX方法传值即可。

好处:(1代码的可读性和可维护性

     2PreparedStatement能够提高 性能

     3极大的提高了安全性

Sql注入只对sql语句的编译过程有破坏作用,PreparedStatement已经编译好了,执行阶段只是把输入串作为数据处理,不会对sql进行解析,准备因此避免了sql注入的过程。

2使用正则表达式过滤传入的参数

检测SQL meta-characters的正则表达式 :

/(\%27)|()|(--)|(\%23)|(#)/ix

修正检测SQL meta-characters的正则表达式 :/((\%3D)|(=))[^ ]*((\%27)|()|(--)|(\%3B)|(:))/i

典型的SQL 注入攻击的正则表达式 :/w*((\%27)|())((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix

检测SQL注入,UNION查询关键字的正则表达式 :/((\%27)|())union/ix(\%27)|()

检测MS SQL Server SQL注入攻击的正则表达式:

/exec(s|+)+(s|x)pw+/ix

3字符串过滤

比较通用的一个方法:

||之间的参数可以根据自己程序的需要添加)

public static boolean sql_inj(String str)

{

String inj_str = "‘|and|exec|insert|select|delete|update|

count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";

String inj_stra[] = split(inj_str,"|");

for (int i=0 ; i < inj_stra.length ; i++ )

{

if (str.indexOf(inj_stra[i])>=0)

{

return true;

}

}

return false;

}

4jsp调用函数判断是否包含非法字符

防止slqurl注入

public class sql_inj{

public static boolean sql_inj(String str)

{

String inj_str = "‘|and|exec|insert|select|delete|update|

count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";

//这里的东西还可以自己添加

String[] inj_stra=inj_str.split("\|");

for (int i=0 ; i < inj_stra.length ; i++ )

{

if (str.indexOf(inj_stra[i])>=0)

{

return true;

}

}

return false;

}

}

5jsp页面判断代码

使用js客户端进行不安全字符的屏蔽,检查是否含有”‘”,”\”,”/”

Mybatis中模糊查询防止sql注入

#{xxx},使用的是PreparedStatement,会有类型转换,所以比较安全;

${xxx},使用字符串拼接sql注入的问题

select * from t_user where name like concat(‘%‘, #{name}, ‘%‘)  

 

 

4、 单点登录

用户的一次登录就能得到其他所有系统的信任,那么关键的是如何产生和存储那个信任

   存储信任

   验证信任

集群环境登录:

第一种:以cookie作为凭证媒介

存在的问题:Cookie不安全

            不能跨域实现免登陆

解决的办法:1.Cookie进行加密(源码不泄露的情况下

Cookie的加密和解密:DES加密和解密、MD5加密和解密(不可逆工具类直接用

       (DES加密的原理:使用了一个56位的密钥以及附加的8位奇偶校验位,产生最大64位的分组大小。迭代的分组密码,将加密的文本分成了两份,使用子密钥对其中一半应用循环功能,然后将输出与另外一半进行“异或”运算;接着进行交换这两半,一直循环下去)

  1. 跨域实现免登陆:配置session共享
    1. 使用Tomcat自身的同步机制复制session到集群中的其他服务器

Tomcat的同步机制是广播形式,也就是说集群中所有Tomcat都是相同的session信息,但是这种情况下,Tomcat越多,效率就会越低,官方给出的最佳集群数量是5Tomcat

   2.使用缓存服务器集中存储session信息达到session共享需求。不管在那台服务器登录成功之后,都会将session信息保存在统一的Redis缓存服务器中,获取用户登录信息。

 

存储信任

验证信任

只要解决了以上的问题,达到了开头讲得效果就可以说是SSO。最简单实现SSO的方法就是用Cookie,实现流程如下所示:

 

 

 

不然发现以上的方案是把信任存储在客户端的Cookie里,这种方法虽然实现方便但立马会让人质疑两个问题:

 

Cookie不安全

不能跨域免登

对于第一个问题一般都是通过加密Cookie来处理,第二个问题是硬伤,其实这种方案的思路的就是要把这个信任关系存储在客户端,要实现这个也不一定只能用Cookie,用flash也能解决,flash的Shared Object API就提供了存储能力。

 

一般说来,大型系统会采取在服务端存储信任关系的做法,实现流程如下所示:

 

以上方案就是要把信任关系存储在单独的SSO系统(暂且这么称呼它)里,说起来只是简单地从客户端移到了服务端,但其中几个问题需要重点解决:

 

如何高效存储大量临时性的信任数据

如何防止信息传递过程被篡改

如何让SSO系统信任登录系统和免登系统

对于第一个问题,一般可以采用类似与memcached的分布式缓存的方案,既能提供可扩展数据量的机制,也能提供高效访问。对于第二个问题,一般采取数字签名的方法,要么通过数字证书签名,要么通过像md5的方式,这就需要SSO系统返回免登URL的时候对需验证的参数进行md5加密,并带上token一起返回,最后需免登的系统进行验证信任关系的时候,需把这个token传给SSO系统,SSO系统通过对token的验证就可以辨别信息是否被改过。对于最后一个问题,可以通过白名单来处理,说简单点只有在白名单上的系统才能请求生产信任关系,同理只有在白名单上的系统才能被免登录。

 

 

1、你们用dubbo是怎么设计接口的?参数返回值是什么?为什么这么设计?

硬件通过通讯模块TCP协议传过一个数据包,你需要接受并解析,解析规则已有

2、在开发过程中,多个使用zookeeper怎么解决端口冲突的问题

3、插入数据的时候,如果有重复的就变成修改,怎么实现

ON DUPLICATE KEY UPDATE(当出现DUPLICATE KEY主键重复错误的时候触发Update操作,当然要求就是表在设计的时候一定要有主键primary key

$sql = "insert into weixin_user(wx_id, wx_name, wx_state, wx_info, wx_lasttime) values (‘$wx_id‘, ‘$wx_name‘, ‘$wx_state‘, ‘$wx_info‘, NOW()) ON DUPLICATE KEY UPDATE wx_name=‘$wx_name‘, wx_state = ‘$wx_state‘, wx_info = ‘$wx_info‘, wx_lasttime = NOW();";

5Dubbo底层原理:

  1. client一个线程调用远程接口,生成一个唯一的ID(比如一段随机字符串,UUID等),Dubbo是使用AtomicLong(原子变量,加了同步锁的)从0开始累计数字的
  2. 将打包的方法调用信息(如调用的接口名称,方法名称,参数值列表等),和处理结果的回调对象callback,全部封装在一起,组成一个对象object
  3. 向专门存放调用信息的全局ConcurrentHashMap里面put(ID, object)
  4. ID和打包的方法调用信息封装成一对象connRequest,使用iosession.write(connRequest)异步发送出去
  5. 当前线程再使用callback的get()方法试图获取远程返回的结果,在get()内部,则使用synchronized获取回调对象callback的锁, 再先检测是否已经获取到结果,如果没有,然后调用callback的wait()方法,释放callback上的锁,让当前线程处于等待状态。
  6. 服务端接收到请求并处理后,将结果(此结果中包含了前面的ID,即回传)发送给客户端,客户端socket连接上专门监听消息的线程收到消息,分析结果,取到ID,再从前面的ConcurrentHashMap里面get(ID),从而找到callback,将方法调用结果设置到callback对象里。
  7. 监听线程接着使用synchronized获取回调对象callback的锁(因为前面调用过wait(),那个线程已释放callback的锁了),再notifyAll(),唤醒前面处于等待状态的线程继续执行(callback的get()方法继续执行就能拿到调用结果了),至此,整个过程结束。

 

以上是关于面试问题的主要内容,如果未能解决你的问题,请参考以下文章

iOS面试准备之思维导图(转)

应届生面试问题及答案

外企英语面试问题大全

留学美国常见面试问题都有哪些

面试的十个问题及回答

技术面试会问很多技术问题吗