最近在做一个社交化的在线商店, 有 Android 和 iOS 客户端, 后台使用 java, 我主要负责接口设计和实现.目前产品已经上线, 现在主要是前端的业务流程优化, 后台的优化和需求更改. 客户端使用 Web app + Native app 的形式.对于菜鸟级我的来说, 以前的小项目都是 10 多张表就搞定了, 现在这个项目有 170 多张表, 想来要完全熟悉全部的业务流程需要花写功夫了.以前都是写的 Java Web 项目, 现在一下来写 Web app 项目有点不习惯, 主要是测试有点麻烦. 接下来, 我将写写来对项目的总体认识以及 Web app 开发和 Java Web 开发的区别 (其实也没多大区别), 算是做一个总结吧.
Web app 和 Native app 的区别Native App:
开发成本非常大。一般使用的开发语言为 Java、C++、Objective-C。
更新体验较差、同时也比较麻烦。每一次发布新的版本,都需要做版本打包,且需要用户手动更新(有些应用程序即使不需要用户手动更新,但是也需要有一个恶心的提示)。
非常酷。因为 Native app ...
相关特征方法区特征
同 Java 堆一样,方法区也是全局共享的一块内存区域
方法区的作用是存储 Java 类的结构信息,当我们创建对象实例后, 对象的类型信息存储在方法堆之中,实例数据存放在堆中;实例数据指的是在 Java 中创建的各种实例对象以及它们的值,类型信息指的是定义在 Java 代码中的常量、静态变量、以及在类中声明的各种方法、方法字段等等;同事可能包括即时编译器编译后产生的代码数据。
JVMS 不要求该区域实现自动的内存管理,但是商用 JVM 一般都已实现该区域的自动内存管理。
方法区分配内存可以不连续,可以动态扩展。
该区域并非像 JMM 规范描述的那样数据一旦放进去就属于 “永久代”; 在该区域进行内存回收的主要目的是对常量池的回收和对内存数据的卸载;一般来说这个区域的内存回收效率比起 Java 堆要低得多。
当方法区无法满足内存需求时,将抛出 OutOfMemoryError 异常。
运行时常量池的特征
运行时常量池是方法区的一部分, 所以也是全局共享的。
其作用是存储 Java 类文件常量池中的符号信息。
class 文件中存在常量池 (非运行时常量池),其在编译 ...
final、finally 和 finalize 虽然长得像孪生三兄弟一样,但是它们的含义和用法却是大相径庭。这一次我们就一起来回顾一下这方面的知识。
final 关键字
我们首先来说说 final。它可以用于以下四个地方:
定义变量,包括静态的和非静态的。
定义方法的参数。
定义方法。
定义类。
我们依次来回顾一下每种情况下 final 的作用。首先来看第一种情况,如果 final 修饰的是一个基本类型,就表示这个变量被赋予的值是不可变 的,即它是个常量;如果 final 修饰的是一个对象,就表示这个变量被赋予的引用是不可变的,这里需要提醒大家注意的是,不可改变的只是这个变量所保存的 引用,并不是这个引用所指向的对象。在第二种情况下,final 的含义与第一种情况相同。实际上对于前两种情况,有一种更贴切的表述 final 的含义的描 述,那就是,如果一个变量或方法参数被 final 修饰,就表示它只能被赋值一次,但是 JAVA 虚拟机为变量设定的默认值不记作一次赋值。
被 final 修饰的变量必须被初始化。初始化的方式有以下几种:
在定义的时候初始化。
final 变量可以在 ...
聚合函数
count 返回结果集中行的数目
sum 返回结果集中所有值得总和
avg 返回结果集中所有值得平均值
max 返回结果集中所有值中最大值
min 返回结果集中所有值中最小值
count
select count([* | all | distinct] expr) from 表名;
: 计算所有选择的行, 包括 null
all : 计算指定列所有的非空行, 默认选项
distinct : 计算指定列所有唯一非空值
sum
select sum([all | distinct] expr) as 别名 from 表名;
avg
select avg(mark) as ‘平均成绩’ from sutdentwhere studentID = 10;输出表 student 中 studentID 为 10 的所有 mark 的平均值
最大值和最小值123select max(mark) as '最高成绩', min(mark) as '最低成绩'from studentwhere examID = 6;
常用 ...
操作表结构
create (创建)
创建表
12345create table [if not exists] 表名( 列名 列类型, 列名 列类型, ...);
创建表并从其他表中复制数据
123create table 表名asselect * from 表名
alter (修改)
添加列定义 (列名必须是原表中不存在的)
1234alter table 表名 add( 列名 数据类型 , ...);
修改列定义 (列名必须是原表中存在的)
1alter table 表名 modify 列名 数据类型;
MySQL 中 一次只能修改一个列定义
如果修改数据列的默认值, 只会对以后插入操作有作用, 对以前已经存在的数据不会有任何影响
删除列
1alter table 表名 drop 列名;
重命名数据表
1alter table 旧表名 rename to/as 新表名;
改列名
1alter table 表名 change 旧列名 新列名 type;
改列名并修改数据类型
1alter table 表名 cha ...
表头 (header): 每一列的名称;
列 (row): 具有相同数据类型的数据的集合;
行 (col): 每一行用来描述某个人 / 物的具体信息;
值 (value): 行的具体信息, 每个值必须与该列的数据类型相同;
键 (key): 表中用来识别某个特定的人或物的方法, 键的值在当前列中具有唯一性
SQL 语句的分类
DQL 查询语句 select
DML 操作语句 insert update delete
DDL 定义语句 create alter drop truncate
DCL 控制语句 grant revoke
实务控制语句 commit rollback savepoint
MySQL 服务的启动、停止与卸载在 Windows 命令提示符下运行:启动: net start MySQL停止: net stop MySQL卸载: sc delete MySQL
MySQL 的登录MySQL 参数
参数
描述
-D, –fatabase = name
打开指定数据库
–delimiter = name
指定分隔符
- ...
public class Propertiesextends Hashtable<Object,Object>Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。新建一个文件内容为键 1 = 值 1键 2 = 值 2…
使用此类可以对文件数据进行持久化保存
方法的使用
load(InputStream inStream); 从输入流中读取属性列表(键和元素对)。
12Properties pro = new Properties();pro.load(new FileInputStream(相对路径或绝对路径));//此方法将抛出FileNotFoundException
getPropertiy(String key) 使用指定的键在此属性列表中搜索属性, 返回 String
getProperty(String key, String defaultValue) 用指定的键在属性列表中搜索属性。返回 String
setProperty(String key, ...
Java Conllection Frame
在集合框架中,分为两种 API:
装载数据的集合类
HashSet 类
ArrayList 类
LinkedList 类
HashMap 类
….
操作集合的工具类
Arrays 类
Collections 类
Iterator 接口java.utilpublic interface IteratorIterator 模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构
12345public interface Iterator{ boolean hasNext();//如果仍有元素可以迭代,则返回 true Object next();//返回迭代的下一个元素。 NoSuchElementException - 没有元素可以迭代。 void remove();//从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。}
Iterable 接口java.langpublic interfac ...
看代码说结果:
1234567public static void main(String[] args){ char x = ‘b’; int i = 0;1. System.out.println(true?x:0); //这个0是short类型2. System.out.println(true?x:1111111110);3. System.out.println(false?i:x);}
要类型转换直接写出的 0 是 short 类型
b9898
解释:条件运算符的 3 个核心要点
如果第二个和第三个操作数具有相同的类型, 那么他就是条件表达式的类型.
如果一个操作数的类型是 byte,shotr 或 char, 而另一个操作数类型是 int 的常量表达式, 条件表达式的值是可以用类型 byte,short 或 char 表示的,
否则, 将操作数类型运用二进制数字提升 (向上转型), 二表达式的类型就是第二个和第三个操作数提升后的类型
System.out.println(true?x:0);对于语句 1 中的条件表达式 ...
Collections 类此类方法众多, 只介绍几个常用方法
sort() 对元素进行排序, 可以传入比较器
max() 返回最大元素, 可以传入比较器
min() 返回最小元素, 可以传比较器
reverse() 反排序
shuffle() 混排
Arrays 类此类包含用来操作数组(比如排序和搜索)的各种方法。方法更多, 还是看 API 吧
比较器Comparable内部比较器public interface Comparable此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。int compareTo(T o)一个类继承了 Comparable 接口后, 重写 compareTo() 方法, 就能按照我们自己的规则排序
例子:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950public class Student implements Comparable< ...
抽象类
把多个类中相同的方法声明给抽取出来。定义到一个类中。
一个方法如果只有方法声明,没有方法体,那么该方法必须定义为抽象方法。
而一个类中如果有抽象方法,那么,该类必须定义为抽象类。
抽象类的特点:
抽象方法和抽象类都必须用 abstract 表示。
一个类继承抽象类的时候;
要么:本身是一个抽象类。
要么:实现抽象类中的所有抽象方法。
抽象类有构造方法, 但是不能实例化, 可以按照多态的使用方式使用。
成员特点:
成员变量
可以是变量,也可以是常量。
构造方法
有 用于子类访问父类构造方法,初始化父类数据
成员方法
可以是抽象,也可以非抽象。
抽象类的好处:
抽象类中的非抽象方法提高了代码的复用性。
抽象类中的抽象方法强制要求子类必须重写某些方法。
抽象类中的几个小问题:
抽象类不能实例化,构造方法有什么用呢?
用于子类访问父类数据的初始化。
如果一个类中没有抽象方法,而类却被定义为了抽象类,请问为什么?
不让创建对象。
abstract 不能和哪些关键字共存:
private: 冲突
final: 冲突
static: 无意义
接 ...
相同的行为, 不同的实现
多态多态, 多种状态, 而多种状态的体现就在不同的实现上面, 也可以说是不同的效果.举个例子:我这里有 3 个杯子, 里面都装了白酒, 你并不知道它们都是什么酒, 只有等你喝过之后才能知道, 第一个杯子是二锅头, 第二个是五粮液, 第三个是茅台.
12Maotai mo = new Maotai();Wine w = mo;
这里我们可以这样理解, 茅台是酒类的一种, 它们之间是继承关系, 当 a 指向了 mo 这个对象的时候, 它会自动向上转型为 Wine, 这也就是说 w 是可以指向茅台这个实例.
这样做的好处就是, 在继承中我们知道子类是父类的扩展, 它可以提供比父类更加强大的功能,如果我们定义了一个指向子类的父类引用类型,那么它除了能够引用父类的共性外,还可以使用子类强大的功能
但是向上转型存在一些缺憾,那就是它必定会导致一些方法和属性的丢失,而导致我们不能够获取它们
所以对于多态我们可以总结如下:
指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若 ...
Java 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。比如可以先定义一个类叫车,车有以下属性:车体大小,颜色,方向盘,轮胎,而又由车这个类派生出轿车和卡车两个类,为轿车添加一个小后备箱,而为卡车添加一个大货箱。
子类拥有父类非 private 的属性和方法。
子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法。(重载)
继承 (类与类的关系)有相同的属性和相同的行为时, 定义为父类,其他的 子类 只需要写特有的属性和方法.
在面向对象中, 可以通过扩展一个已有的类, 并继承该类的属性和行为,来创建一个新的类, 从而达到代码的复用.
继承是所有 OOP 语言不可缺少的部分,在 java 中使用 extends 关键字来表示继承关系。当创建一个类时,总是在继承,如果没有明确指出要继承的类,就总是隐式地从根类 Object 进行继承。
继承不会继承父类的构造方法因为:
语法上如果继承来了父 ...
新时代码农
未读什么是封装
隐藏对象的属性和实现细节,仅对外公开接口;
控制在程序中属性的读和修改的访问级别;
将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成 “类”,其中数据和函数都是类的成员。
通俗的说就是:利用抽象数据类型将数据和基于数据的操作组合在一起, 是其构成一个不可分割的独立实体, 数据被保护在抽象数据类型的内部, 尽可能的隐藏内部的细节, 只保留一些对外的接口使之与外部发生联系.用户无需知道内部的实现细节, 但可以通过该对象对外提供的接口来访问该对象.
封装的好处
良好的封装能够减少耦合
类内部的结构可以自由修改
可以对成员进行更精确的控制
隐藏信息, 实现细节
JavaBeanJavaBean 规范: 标准 java 类 Sun 公司规定为私有属性提供符合命名规范的 set 和 get 方法
JavaBean 必须声明为 public class
JavaBean 的所有属性必须声明为 private
通过 setter 和 getter 方法设值和取值
通过 JSP 调用是, 则需要一个无参的构造方法
编写代码要 ...