问题

说一下爬虫反爬的思路

从数据的爬取和使用这两个角度进行反爬虫:

增大数据的爬取成本

  • 数据访问过于频繁时,增加验证码等校验机制
  • 检测到爬虫时,对相关IP进行封禁、黑名单处理
  • 限制一定时间内的访问次数

增大数据的使用成本

  • 对于文本类数据,在前端网页对数据展示时,使用特殊的字体文件,在爬虫
  • 爬取到的数据(或部分数据)变成无法直接识别的乱码
  • 对于图片类数据,可以图片中添加水印

UserAgent中有哪些信息

以自己的浏览器的User-Agent为例:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36

主要包括了操作系统、浏览器名称以及版本、渲染引擎。

使用IP进行爬虫的判断一定准确吗

不一定。

对爬虫程序进行识别,主要通过数据访问频率、User-Agent等请求标识符等进行识别。

对于爬虫程序,可以通过使用IP池,并模仿正常的频率,达到大量爬取数据的目的,此时IP难以识别出爬虫。

对于正常用户,在网络不佳不断请求数据或者打开多个页面时,或者在某个使用公网IP的局域网内有多用户同时访问时,也可能出现类似爬虫的行为,此时IP容易被误判为爬虫。

Python中如何获取IP

socket.gethostbyname(socket_name)

Django的默认端口

8000

数据库中如何部分模糊查询

使用like关键字或者基于全文索引的查询

like的效率如何

较低。

对于有索引的数据列,左模糊查询会进行全表扫描(如:like ‘%java%’),效率较低;右模糊查询会使用索引(如:like ‘java%’),效率相对较高。

全文索引的实现

相关数据结构

倒排索引(反向索引)。

在指定的列中(可以是多个),对每个单词都保存这个单词所在的文档、在文档中的位置。如果对多个列创建了全文索引,则会将这些列全部拼接成一个字符串,然后进行索引。使用辅助表information_schema.INNODB_FT_INDEX_TABLE来进行保存。

辅助表information_schema.INNODB_FT_INDEX_TABLE中的数据字段

字段名 作用
WORD 索引列中提取出的具体单词
FIRST_DOC_ID 首次出现的文档id
LAST_DOC_ID 最后出现的文档id
DOC_COUNT 此单词出现在 FULLTEXT 索引中的行数
DOC_ID 包含单词的行的文档ID
POSITION 该单词在DOC_ID所标示的文档中的位置

单词的一些提取过滤的规则

  1. 不会使用在停用词列表中的单词。

    停用词列表:默认根据通用英语的使用来设置,也可以通过ft_stopword_file来指定外部文件。

  2. 不使用长度不在指定的长度范围内的单词:

非英文字段的全文索引

对于英文的字段,可以通过空格来进行分词。对于非英文的字段,如中文、日文等,则无法直接通过特殊字符进行分词,需要依靠其他插件实现。

5.7.6之前,全文索引只支持英文全文索引,不支持中文全文索引,需要利用分词器把中文段落预处理拆分成单词,然后存入数据库。5.7.6开始,MySQL内置了ngram全文解析器,用来支持中文、日文、韩文分词。

对于非英文的字段,通过设置分词的长度(单词的粒度)来进行分词。如设置粒度为2,则会把每2个字分成一个词进行索引。

相关参考:

知乎:请大神推荐符合描述的中文全文检索引擎有哪些?

MySql 5.7 中文文档- 24.32.12 INFORMATION_SCHEMA INNODB_FT_INDEX_TABLE表

维基百科:倒排索引

简书:MySQL 5.7 中文全文检索使用教程

高性能MySQL 第三版: 7.10 全文索引

介绍一下MySQL的不同引擎特点

引擎 特点
InnoDB 支持事务、支持行级锁、聚集索引、采用MVCC支持高并发
MyISAM 不支持事务、只支持表级锁、支持全文索引、不支持并发

为什么要使用事务,不使用的话会有什么后果

保证数据的一致性和操作的有效性,并方便数据的版本控制。具体可以联系事务的ACID特性和隔离级别进行回答。

在并发的情况下,如果不使用事务,则非常容易出现各种诸如“不可重复读”、“读脏数据”等问题,难以保证操作的有效性。

在发生错误时,使用事务的话,能方便的进行RollBack操作,将进行到一半出错的操作回退到操作前的状态,不会将错误的数据写入,导致数据的不一致。如A给B转账,如果在A的账户扣完钱以后出现错误,未能在B的账户中加上对应金额,不用事务的话,则需要手动撤销掉错误前的操作。

需要退回到某个数据库版本时,使用事务能方便地根据这一段时间内的操作进行UnDo回滚,在备份和恢复时较为方便。

项目中如何使用事务的

数据操作的时候都会使用,try{……} catch(){……} finally{……},正常操作时在try中提交,出错时在finally中回滚。

介绍一下Nginx的作用

反向代理、负载均衡

安卓端在与服务器通信时如何校验权限

OAuth(开放授权)标准,如:Spring-auth2

或者基于Token实现一套校验机制。

Servlet自带Session吗

Servlet不自带Session

  • Session的创建

    Session的创建是在调用Request对象的getSession(true)方法时创建的,一般在第一次获取Session对象时创建。

    getSession(boolean create):在当前会话没有Session时,如果create值为true,则会创建一个Session对象,如果为false则会返回null。当前会话已有对应的Session的话就直接返回这个Session

  • Session在服务器端的存储

    Session保存于内存中。

  • Session在客户端的存储

    Cookie中保存Sessionid

不同用户会话的Session是如何区分的

Session之间通过jsessionid作为其id(用于唯一标识的主键),通过jsessionid区分不同的Session

客户端在首次请求服务器时,服务器会创建本次会话的Session,并返回一个保存了jsessionidCookie。在本次会话之后的请求中,都会带上这个Cookie以标识本次会话的Session

如果客户端禁用了Cookie,则可以将jsessionidurl参数的形式发送给服务器。

在服务器中,Session默认的过期时间是30分钟,但是保存其idCookie的默认生命周期就是会在浏览器关闭以后被销毁。所以,更多的情况下表现为关闭浏览器后再次访问时Session就”没了“,其实是因为再次访问时没有携带上一次会话的jsessionid,所以无法找到这个Session

Token的数据格式

本质是由服务器生成的一串字符串。

JWT:JSON Web Token

JWT是目前应用较广的一种Token解决方案。主要由三部分组成:Header 头部、Payload 有效载荷、Signature 签名。

  • typ:type,token的类型,一般为JWT
  • alg:algorithm,加密的算法

Payload

  • iss:Issuer,发行者
  • sub:Subject,主题
  • aud:Audience,受众
  • exp:Expiration Time,过期时间
  • nbf:Not Before,最早的生效时间
  • iat:Issued At,发布时间
  • jti:JWT ID,JWT的唯一标识符
  • 自定义数据

Signature

加密后的HeaderPayload数据,用于校验。

参考:

阮一峰:JSON Web Token 入门教程

RFC 7519 - JSON Web Token (JWT)

总结

虽然面的是Java开发的岗,但是也问到了python,一是自己简历中的项目有python相关,二是面试官所在部门的技术栈中除了Java外也包含了python,所以面试官可能也比较感兴趣。

整体面试的题目来说,范围较广,深度一般。涉及的知识面较广,除了Java外还涉及到了python相关的很多内容,但在每一个知识领域内问的都不算很深,基本上也是结合简历中的项目稍微做了一下拓展深入。

就个人而言,一是很多底层的机制还需要加强理解,像ServletSession、全文索引的实现这些问题当时都回答的不是很准确。其次便是要加强应用方面的认识,对于项目中的一些技术和解决方案,不仅要会用还要从“为什么要用这个”、“不用会怎么样”、“其他的方案如何”等角度去思考、去拓展,所幸爬虫那块之前项目中稍有了解,也算回答的上来。


讨论帖