一个Java小白的面试之旅总结

前言

今天去了一家国内领先的可视化智能硬件公司面试。面试的我是技术总监。为人和蔼,和他交谈中,我还有一股紧张。面试中,能感觉他功力深厚,同时也学到了很多东西。个人感觉,我对自己的面试结果不是很满意。技术总监问的问题比较深入,也是我平时比较疏忽的知识点。


关于Int类型的理解

面试官问我int类型占几个字节。我是这样说的: "占4个字节,在内存中占32位。可能不同的操作系统占的字节不一样。" 我真的是强行装逼,给自己挖坑。面试官说:"为什么不一样"。 然后我说:"我记得博客上面是这样说的。"

可能是面试官说的意思是在Java语言中int类型占几个字节。而我印象中的那篇博客说的是int类型跟OS有关,所以面试的要老老实实回答问题。

  • 操作系统是32位/64位,寻址空间不同。寻址空间一般指的是CPU对于内存寻址的能力。也就是最多用到多少内存的一个问题。32位的CPU一次就能处理4个字节,64位的CPU一次可以处理8个字节。int类型在32位和64位系统中都是4个字节。
  • Java程序不是直接运行在OS上,而是运行在JVM上,JVMclass程序在不同OS上的基础类型长度固定,也就是int类型就是4个字节。所有平台上的JVM向上提供给Java字节码程序的接口完全相同,但向下适应不同平台的接口则互不相同。

Int类型的使用

忘记是我主动抛出Int类型的使用,还是面试官给我抛出的。请原谅我的记性太差了。所以不要强行显摆自己的实力,你在技术总监面前什么都不是。我举的是二分法,寻找中间元素下标的例子。" int mid = (a + b) / 2。int类型的范围是-2^31 ~ 2^31 - 1。我是这样说的:a如果是一个足够大的int类型数据,b如果也是一个足够大的int类型数据。那么a + b 数据的范围肯定超过了int类型的范围,会造成内存泄露。我的做法是改成 int mid = a + (b - a) / 2。这样可以避免造成内存的泄露,同时减少了内存的开销。"

说出这个答案,我心中一阵窃喜。然后面试官又给我抛出了这样的问题,“那你为什么不用int mid = a /2 + b/2 "。但是我觉得这个问题还好,不是特别难。我就说: "这种做法的性能没有我的好,因为 a / 2 做了一次运算,然后 b / 2 又做了一次运算,然后把他们加在一起又做了一次运算,内存开销比较大。"

然后面试官说,“这种回答并不能说服我,可能你的做法性能上确实比较好,但是根本原因是内存开销的问题吗?”。当时我就懵了,不知道说什么了。最后面试官告诉了答案:“计算机不擅长做除法运算!”

  • 所有数字在计算机底层都是以二进制存在的。计算机以补码的形式保存所有的整数。计算机不擅长做除法。除法一般都是减法和移位的综合体。
  • Java支持的位运算符有7个:
    • &:按位与。当两位同时为1时才返回1
    • |:按位或。只要有一位为1即可返回1
    • ~:按位非。单目运算符,将操作数的每个位(包括符号位)全部取反。
    • ^:按位异或。当两位相同时返回0,不同时返回1
    • <<:左移运算符。
    • >>:右移运算符。
    • >>>:无符号位右移运算符。比如-5>>>2-5无符号右移动2位后,左边空出2位后,空出来的2位用0去补充。
  • 突然想到int mid = a / 2 + b / 2 这种做法还有其他的问题,就是如果ab都是一个偶数,这样得出的结果不会有影响,这样假设a = 2b = 2,那么算式1算式2得出的结论mid都是等于2。 那么假如a = 1, b = 3算式1得出的结论是2算式2得出的结论是1。显而易见,算式2会造成精度缺失,最后就会导致二分法错误。

字符型

  • 字符型通常用于表示单个的字符,字符型值必须使用单引号括起来,Java语言使用16位的Unicode字符集作为编码方式,而Unicode被设计成支持世界上任何书面语言的字符,包括中文字符,因此Java程序支持各种语言的字符。

表单重复提交

后面,我就不具体讲和面试官的细节了。直接概要出面试官抛出的问题和复盘分析。

我们在添加数据的时候,如果表单重复提交,肯定会造成数据库表的数据重复。

  • 客户端生成token,存在于表单的hidden域,接着把token存入session中。表单提交后,后台比较表单的tokensession中的token,如果相等的话,就表示表单没有重复提交,如果不相等的话,证明表单重复提交。如果表单没有重复提交的话,就把session中的token清空。假如发送100条请求,第一条请求肯定是会通过的,后面的99条请求会因为session中的tokennull,造成请求失败,从而防止了表单重复提交。
  • 当客户端输入的数据提交到后台,后台添加的数据会与数据库表中的数据进行比较,如果不重复则写入,可以防止表单重复提交。如果2个对象相同的话,那么它们的hashCode肯定相同。如果2个对象的hashCode相同,那么它们不一定是相同的对象。重写equals()方法,必须要重写hashCode()方法。
  • 数据库中,增加一个int类型的hash值字段,加上索引。将所有的业务信息(排除主键idcreate_time之类的字段)计算hash值。往表里面添加数据的时候,先计算hash值,然后用hash值去数据库中查询,查询结果为多个的时候,可以去做精确比较。

hashCode()解决数据重复,是一个不错的选择。


MySQL数据库

基本概念

  • DML(Data Manipulation Language): 数据操作语言,主要由insert, delete, update三个关键字完成。
  • DDL(Data Definition Language): 数据定义语言,主要由create, alter, drop, truncate这四个关键字完成。
  • DCL(Data Control Language):数据控制语言,主要由grant(准许)和 revoke(撤销)两个关键字组成。
  • primary key : PRIMARY KEY(id), 有2个作用,一是约束作用(constraint),用来规范一个存储主键和唯一性,但是同时也在该key上建立了一个索引。
  • unique key: UNIQUE KEY deal_id_uk(deal_id), CONSTRAINT deal_id_uk UNIQUE(deal_id)两种写法都可以,有2个作用。一是规范数据的唯一性,建立索引。
  • key : 建立索引。
  • index : create index deal_id_idx on employees(deal_id)index是数据库的物理结构,索引总是属于数据表,当它和数据表一样都是属于数据库对象。创建索引的唯一作用是加速对表的查询,索引通过使用快速路径访问方法快速定位数据,从而减少了磁盘的I/O

基础概念说完了,怎么去规范的创建数据表呢。再此部分引用阿里巴巴Java开发手册的的建表规约索引规约。

  • 表达是与否的概率的字段,必须使用is_xxx的方式命名,数据类型是unsigned tinyint(0-255),1代表删除,0表示未删除。任何字段如果是非负数,必须是unsigned
  • char的长度是固定的,而varchar的长度是可变的,比如我存一个字符串,叫“cmazxiaoma”,对于char(20)来说表示你存储的字符将占20个字节,其中包括10个空闲字符,而同样varchar(20)只会占用10个字节,20个字节只是最大值而已。
  • varchar是可变长字符串,不预先分配空间,长度不要超过5000,如果存储长度大于此值,定义字段类型为text,独立出来一张表。用主键去对应,避免影响其他字段的索引效率。
  • 字段允许冗余,以提高查询性能,但必须考虑数据的一致,冗余字段应该遵循:不是频繁修改的字段,不是varchar超长字段,更不是text字段。
  • 业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。不要以为唯一索引影响insert的速度,这个速度的损耗可以忽略,但是提高查询速度是明显的,另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据的产生
  • 区分度与索引长度的权衡。索引长度越低,索引在内存中占的长度越小,排序越快。然而区分度就很低了,不利于查找。索引长度越长,区分度越高,虽然利于查找,但是索引在内存占的空间就越多了。

数据库三大范式

  • 列名不可再分,保持原子性。
  • 每一个非主属性必须依赖于主键。消除部分函数依赖
  • 除了主键之外,其他属性之间不能相互依赖。消除传递依赖。

尾言

心之所向,素履以往。生如逆旅,一苇以航。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Crossin的编程教室

每一个程序员要遵守的一些优秀编程风格

无论你是业余的还是专业的程序员,正确的编程风格,不但有助于提升软件产品的功能,还可以明显减少软件灾难的产生。今天,我们就来探讨一下有助于我们获取更佳编程风格的一...

3458
来自专栏程序员互动联盟

【新技术分享】C++17 最新进展

C++标准委员会最近在夏威夷的科纳召开了一次会议,大家可能关心最新的进展,但是按照以往的情况,某些文件需要很久才会公开。会议进行的时候,大家都在忙着修订自己的文...

3446
来自专栏点滴积累

shapeless官方指南翻译写在前面

目录 前言 Shapeless简介 The Type Astronaut's Guide to Shapeless简介 总结 一、前言        在我的20...

3737
来自专栏java工会

编写高质量代码的思考

最近在看《代码大全》,可以说是一本软件开发的百科全书,特别厚,但是干货也很多。平时写代码,代码规范是一个最低的要求(很多老代码连最低要求都达不到),为什么要这样...

850
来自专栏惨绿少年

Python入门篇

3954
来自专栏一个会写诗的程序员的博客

Java新手极简指北手册

为什么我先拿“数据结构和算法”说事捏?这玩意是写程序最最基本的东东。不管你使用 Java 还是其它的什么语言,都离不开它。而且这玩意是跨语言的,学好之后不管在哪...

1211
来自专栏编程

PLC编程优化方法,让程序运行提速!

PLC、DCS、仪器仪表、电气技术资料,一网打尽 通过本方法优化可以极大的减少程序语句数,使PLC程序更简洁、可读性更好,由于不需要做耗时的类型转换,程序运行效...

2149
来自专栏数据科学与人工智能

【Python环境】如何使用正确的姿势进行高效Python函数式编程?

关于函数式编程 有哪些函数式语言? 其实函数是语言很早就出现了,上世纪30年代出现的Lambda和50年代的LISP,比面向过程和对象的语言出现的更早,现代的C...

22410
来自专栏Jimoer

经历的面试题,先做下部分总结。

1653
来自专栏哲学驱动设计

EntityFramework 元数据 设计分析

    由于之前已经尝试使用过 EF CodeFirst CTP4,所以这次在EF4.1发布的第三天,在 OEA 框架中已经支持使用它来实现数据访问层。而且,我...

1888

扫码关注云+社区

领取腾讯云代金券