lv mama面试题

1.如何优化java代码?

可供程序利用的资源(内存、CPU时间、网络带宽等)是有限的,优化的目的就是让程序用尽可能少的资源完成预定的任务。优化通常包含两方面的内容:减小代码的体积,提高代码的运行效率。

答案在此链接下:http://hi.baidu.com/sickcat/blog/item/98775be705594927b8382049.html

2.如何优化前台代码?

3.如何做分页数据库查询,SQL语句

第n页. 每页显示x条
mysql: SELECT * FROM USER limit (n - 1) * x, x
sql2000: SELECT * FROM (SELECT TOP n * x FROM USER) WHERE id NOT IN (SELECT TOP (n - 1) * x id FROM USER);
oracle: SELECT * FROM (
SELECT users.*, ROWNUM RN FROM (SELECT * FROM USER) users
WHERE ROWNUM < (n * x)
)
WHERE RN >= (n - 1) * x

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Vector;

/**
 * Pager, 基于 JDBC 2.0 滚动机制的分页程序, 在 MySQL, SQLServer, Access, Oracle 下测试通过.
 * 
 */
public class Pager {
    /** Used database connection */
    Connection conn = null;
    public Pager() {
    }
    /**
     * 
     * 分页功能, 返回当页的数据(JDBC 2.0 实现).
     * @param currentPage
     * 当前页面数(取值范围: 从 1 开始有效, 0 自动改为 1)
     * @param pageCount
     * 每页显示记录
     * @return a Vector - 数据列表
     */
    public Vector pageData(int currentPage, int pageCount) {
        
        Vector results = new Vector();
        String tableName = "table_name";// 要处理的表格名
        ResultSet rs = null;
        String sql = "SELECT * FROM " + tableName;
        Statement stmt = null;
        try {
            // 生成可滚动的结果集表达式
            stmt = conn.createStatement(ResultSet.
            TYPE_SCROLL_SENSITIVE,
            ResultSet.CONCUR_READ_ONLY);
            rs = stmt.executeQuery(sql);
            int count = recordCount(); // 总记录数
            int totalPage = (int) Math.ceil(1.0 * count / pageCount); // 总页面数
            if (currentPage <= 0) {
                currentPage = 1;
            }
            // 超出页码范围, 不返回数据
            if (currentPage > totalPage) {
                currentPage = totalPage;
                return results;
            }
            if ((currentPage - 1) * pageCount > 0) {
                // 移动结果集数据到当前页
                rs.absolute((currentPage - 1) * pageCount);
            }
            // rs.absolute(0); 在 ODBC 下会导致如下异常:java.sql.SQLException: Cursor
            // position (0) is invalid
            int i = 0; // Readed pages
            while (rs.next() && i < pageCount) {
                i++;
            }
        } catch (Exception exception) {
            System.out.println("Occur a error in " + getClass()
            + ".pageData() : " + exception.getMessage());
        } finally {
            closeJDBCResource(stmt);
            closeJDBCResource(rs);
            closeJDBCResource(conn);
        }
        return results;

    }

    /**
     * 
     * 返回当前数据库中记录的总数.
     * @return int 记录总数
     */
    public int recordCount() {
        int allCount = -1;
        String tableName = "table_name";// 要处理的表格名
        String sql = "SELECT COUNT(*) FROM " + tableName;
        ResultSet rs = null;
        Statement stmt = null;
        try {
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
            if (rs.next()) {
                allCount = rs.getInt(1);
            }
        } catch (Exception exception) {
            System.out
            .println("Occur a error in " + getClass()
            + ".recordCount() : " + exception.getMessage());
        } finally {
            closeJDBCResource(stmt);
            closeJDBCResource(rs);
            closeJDBCResource(conn);
        }
        return allCount;

    }

    /**
     * Close a jdbc resource, such as ResultSet, Statement, Connection.... All
     * these objects must have a method signature is void close().
     * @param resource -
     * jdbc resouce to close
     * 
     */
    public static void closeJDBCResource(Object resource) {
        try {
            Class clazz = resource.getClass();
            java.lang.reflect.Method method = clazz.getMethod("close", null);
            method.invoke(resource, null);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    /**
     * 
     * Test page.
     * @param args
     * 
     */
    public static void main(String[] args) {

        // 分页, 读取第一页数据, 共读取5个记录
        Vector data = new Pager().pageData(1, 5);
        // TODO: process value object, 更改类名
        /*
         * for(int i = 0; results != null && i < data.size(); i++) {
         * 
         * ValueObject bean = (ValueObject)data.get(i);
         *  }
         */
    }

}

Hibernate 可以实现分页查询,

从第2万条开始取出100条记录

Query q = session.createQuery("from Cat as c");;
q.setFirstResult(20000);;
q.setMaxResults(100);;
List l = q.list();

 那么Hibernate底层如何实现分页的呢?实际上Hibernate的查询定义在net.sf.hibernate.loader.Loader这个类里面,仔细阅读该类代码,就可以把问题彻底搞清楚。

Hibernate2.0.3的Loader源代码第480行以下:

if (useLimit)
 sql = dialect.getLimitString(sql);		
 PreparedStatement st = session.getBatcher();
 prepareQueryStatement(sql, scrollable);

如果相应的数据库定义了限定查询记录的sql语句,那么直接使用特定数据库的sql语句。

然后来看net.sf.hibernate.dialect.MySQLDialect:

public boolean supportsLimit(); {  
  return true;  
} 
public String getLimitString(String sql); {  
  StringBuffer pagingSelect = new StringBuffer(100);;  
  pagingSelect.append(sql);;  
  pagingSelect.append(" limit ?, ?");;  
  return pagingSelect.toString();;  
}  

这是MySQL的专用分页语句,再来看net.sf.hibernate.dialect.Oracle9Dialect:

public boolean supportsLimit(); {
  return true;
}

public String getLimitString(String sql); {
  StringBuffer pagingSelect = new StringBuffer(100);
  pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
  pagingSelect.append(sql);
  pagingSelect.append(" ); row_ where rownum <= ?); where rownum_ > ?");
  return pagingSelect.toString();
}

 Oracle采用嵌套3层的查询语句结合rownum来实现分页,这在Oracle上是最快的方式,如果只是一层或者两层的查询语句的rownum不能支持order by。

如果数据库不支持分页的SQL语句,那么根据在配置文件里面
#hibernate.jdbc.use_scrollable_resultset true
默认是true,如果你不指定为false,那么Hibernate会使用JDBC2.0的scrollable result来实现分页,看Loader第430行以下:

if ( session.getFactory();.useScrollableResultSets(); ); {
  // we can go straight to the first required row
  rs.absolute(firstRow);
}
else {
  // we need to step through the rows one row at a time (slow);
  for ( int m=0; m<firstRow; m++ ); rs.next();
}

如果支持scrollable result,使用ResultSet的absolute方法直接移到查询起点,如果不支持的话,使用循环语句,rs.next一点点的移过去。

可见使用Hibernate,在进行查询分页的操作上,是具有非常大的灵活性,Hibernate会首先尝试用特定数据库的分页sql,如果没用,再尝试Scrollable,如果不行,最后采用rset.next()移动的办法。

在查询分页代码中使用Hibernate的一大好处是,既兼顾了查询分页的性能,同时又保证了代码在不同的数据库之间的可移植性。

4.在项目中有无使用同步和异步,举例说明?

5.如何优化cache?

6.ibats是否了解及相应问题?

7.hibernate是否做过配置,如何使用,及其作用?

8.对JMS是否了解及做说明工作机制和原理?

jms即Java消息服务(Java Message Service)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。

JMS有以下元素组成。

  JMS提供者

  连接面向消息中间件的,JMS接口的一个实现。提供者可以是Java平台的JMS实现,也可以是非Java平台的面向消息中间件的适配器。

  JMS客户

  生产或消费基于消息的Java的应用程序或对象。

  JMS生产者

  创建并发送消息的JMS客户。

  JMS消费者

  接收消息的JMS客户。

  JMS消息

  包括可以在JMS客户之间传递的数据的对象

  JMS队列

  一个容纳那些被发送的等待阅读的消息的区域。队列暗示,这些消息将按照顺序发送。一旦一个消息被阅读,该消息将被从队列中移走。

  JMS主题

  一种支持发送消息给多个订阅者的机制。

JMS模型

  Java消息服务应用程序结构支持两种模型:

  点对点或队列模型

  发布者/订阅者模型

  在点对点或队列模型下,一个生产者向一个特定的队列发布消息,一个消费者从该队列中读取消息。这里,生产者知道消费者的队列,并直接将消息发送到消费者的队列。这种模式被概括为:

  只有一个消费者将获得消息

  生产者不需要在接收者消费该消息期间处于运行状态,接收者也同样不需要在消息发送时处于运行状态。

  每一个成功处理的消息都由接收者签收

  发布者/订阅者模型支持向一个特定的消息主题发布消息。0或多个订阅者可能对接收来自特定消息主题的消息感兴趣。在这种模型下,发布者和订阅者彼此不知道对方。这种模式好比是匿名公告板。这种模式被概括为:

  多个消费者可以获得消息

  在发布者和订阅者之间存在时间依赖性。发布者需要建立一个订阅(subscription),以便客户能够购订阅。订阅者必须保持持续的活动状态以接收消息,除非订阅者建立了持久的订阅。在那种情况下,在订阅者未连接时发布的消息将在订阅者重新连接时重新发布。

  使用Java语言,JMS提供了将应用与提供数据的传输层相分离的方式。同一组Java类可以通过JNDI中关于提供者的信息,连接不同的JMS提供者。这一组类首先使用一个连接工厂以连接到队列或主题,然后发送或发布消息。在接收端,客户接收或订阅这些消息。

传递消息方式

  JMS现在有两种传递消息的方式。标记为NON_PERSISTENT的消息最多投递一次,而标记为PERSISTENT的消息将使用暂存后再转送的机理投递。如果一个JMS服务离线,那么持久性消息不会丢失但是得等到这个服务恢复联机时才会被传递。所以默认的消息传递方式是非持久性的。即使使用非持久性消息可能降低内务和需要的存储器,并且这种传递方式只有当你不需要接收所有的消息时才使用。

  虽然JMS规范并不需要JMS供应商实现消息的优先级路线,但是它需要递送加快的消息优先于普通级别的消息。JMS定义了从0到9的优先级路线级别,0是最低的优先级而9则是最高的。更特殊的是0到4是正常优先级的变化幅度,而5到9是加快的优先级的变化幅度。举例来说: topicPublisher.publish (message, DeliveryMode.PERSISTENT, 8, 10000); //Pub-Sub 或 queueSender.send(message,DeliveryMode.PERSISTENT, 8, 10000);//P2P 这个代码片断,有两种消息模型,映射递送方式是持久的,优先级为加快型,生存周期是10000 (以毫秒度量 )。如果生存周期设置为零,这则消息将永远不会过期。当消息需要时间限制否则将使其无效时,设置生存周期是有用的。

  JMS定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据,提供现有消息格式的一些级别的兼容性。

  · StreamMessage -- Java原始值的数据流

  · MapMessage--一套名称-值对

  · TextMessage--一个字符串对象

  · ObjectMessage--一个序列化的 Java对象

  · BytesMessage--一个未解释字节的数据流

JMS应用程序接口

ConnectionFactory 接口(连接工厂)

  用户用来创建到JMS提供者的连接的被管对象。JMS客户通过可移植的接口访问连接,这样当下层的实现改变时,代码不需要进行修改。 管理员在JNDI名字空间中配置连接工厂,这样,JMS客户才能够查找到它们。根据消息类型的不同,用户将使用队列连接工厂,或者主题连接工厂。

Connection 接口(连接)

  连接代表了应用程序和消息服务器之间的通信链路。在获得了连接工厂后,就可以创建一个与JMS提供者的连接。根据不同的连接类型,连接允许用户创建会话,以发送和接收队列和主题到目标。

Destination 接口(目标)

  目标是一个包装了消息目标标识符的被管对象,消息目标是指消息发布和接收的地点,或者是队列,或者是主题。JMS管理员创建这些对象,然后用户通过JNDI发现它们。和连接工厂一样,管理员可以创建两种类型的目标,点对点模型的队列,以及发布者/订阅者模型的主题。

MessageConsumer 接口(消息消费者)

  由会话创建的对象,用于接收发送到目标的消息。消费者可以同步地(阻塞模式),或异步(非阻塞)接收队列和主题类型的消息。

MessageProducer 接口(消息生产者)

  由会话创建的对象,用于发送消息到目标。用户可以创建某个目标的发送者,也可以创建一个通用的发送者,在发送消息时指定目标。

Message 接口(消息)

  是在消费者和生产者之间传送的对象,也就是说从一个应用程序传送到另一个应用程序。一个消息有三个主要部分:

  消息头(必须):包含用于识别和为消息寻找路由的操作设置。

  一组消息属性(可选):包含额外的属性,支持其他提供者和用户的兼容。可以创建定制的字段和过滤器(消息选择器)。

  一个消息体(可选):允许用户创建五种类型的消息(文本消息,映射消息,字节消息,流消息和对象消息)。

  消息接口非常灵活,并提供了许多方式来定制消息的内容。

Session 接口(会话)

  表示一个单线程的上下文,用于发送和接收消息。由于会话是单线程的,所以消息是连续的,就是说消息是按照发送的顺序一个一个接收的。会话的好处是它支持事务。如果用户选择了事务支持,会话上下文将保存一组消息,直到事务被提交才发送这些消息。在提交事务之前,用户可以使用回滚操作取消这些消息。一个会话允许用户创建消息生产者来发送消息,创建消息消费者来接收消息。

9.在项目开发中如何利用SOA?

10.项目中利用到的缓存,如何实现及机制?

11.hashmap and hasptable的区别,及实现原理?

1. HashMap概述:

HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

 

2. HashMap的数据结构:

java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。

Entry就是数组中的元素,每个 Map.Entry 其实就是一个key-value对,它持有一个指向下一个元素的引用,这就构成了链表。

3. HashMap的存取实现:

 1) 存储:

2) 读取:

public V get(Object key) {
    if (key == null)
        return getForNullKey();
    int hash = hash(key.hashCode());
    for (Entry<K,V> e = table[indexFor(hash, table.length)];
        e != null;
        e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
            return e.value;
    }
    return null;
}

4. HashMapresizerehash):

HashMap中的元素越来越多的时候,hash冲突的几率也就越来越高,因为数组的长度是固定的。所以为了提高查询的效率,就要对HashMap的数组进行扩容,数组扩容这个操作也会出现在ArrayList中,这是一个常用的操作,而在HashMap数组扩容之后,最消耗性能的点就出现了:原数组中的数据必须重新计算其在新数组中的位置,并放进去,这就是resize

那么HashMap什么时候进行扩容呢?当HashMap中的元素个数超过数组大小*loadFactor时,就会进行数组扩容,loadFactor的默认值为0.75,这是一个折中的取值。也就是说,默认情况下,数组大小为16,那么当HashMap中元素个数超过16*0.75=12的时候,就把数组的大小扩展为 2*16=32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常消耗性能的操作,所以如果我们已经预知HashMap中元素的个数,那么预设元素的个数能够有效的提高HashMap的性能。

5. HashMap的性能参数:

HashMap 包含如下几个构造器:

HashMap():构建一个初始容量为 16,负载因子为 0.75 HashMap

HashMap(int initialCapacity):构建一个初始容量为 initialCapacity,负载因子为 0.75 HashMap

HashMap(int initialCapacity, float loadFactor):以指定初始容量、指定的负载因子创建一个 HashMap

HashMap的基础构造器HashMap(int initialCapacity, float loadFactor)带有两个参数,它们是初始容量initialCapacity和加载因子loadFactor

initialCapacityHashMap的最大容量,即为底层数组的长度。

loadFactor:负载因子loadFactor定义为:散列表的实际元素数目(n)/ 散列表的容量(m)

负载因子衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。对于使用链表法的散列表来说,查找一个元素的平均时间是O(1+a),因此如果负载因子越大,对空间的利用更充分,然而后果是查找效率的降低;如果负载因子太小,那么散列表的数据将过于稀疏,对空间造成严重浪费。

HashMap的实现中,通过threshold字段来判断HashMap的最大容量:

threshold = (int)(capacity * loadFactor);

  结合负载因子的定义公式可知,threshold就是在此loadFactorcapacity对应下允许的最大元素数目,超过这个数目就重新resize,以降低实际的负载因子。默认的的负载因子0.75是对空间和时间效率的一个平衡选择。当容量超出此最大容量时, resize后的HashMap容量是容量的两倍:

if (size++ >= threshold)   
    resize(2 * table.length); &nbsp;

6. Fail-Fast机制:

我们知道java.util.HashMap不是线程安全的,因此如果在使用迭代器的过程中有其他线程修改了map,那么将抛出ConcurrentModificationException,这就是所谓fail-fast策略。

这一策略在源码中的实现是通过modCount域,modCount顾名思义就是修改次数,对HashMap内容的修改都将增加这个值,那么在迭代器初始化过程中会将这个值赋给迭代器的expectedModCount

12.ArrayList and LinkedList的区别?

13.项目中利用的Jquery和json,javascirpt的在哪些地方使用及说明?

14.什么时候使用abstract class和interface?(个人见解

1。从类的层次结构上看,抽象类通常是在层次的顶端,但在实际的设计实践当中,抽象类应当是最后出现的

2。interface从表面上看,和抽象类很相似,但用法完全不同。它的基本功能就是把一些毫不相关的类(概念)集合在一起形成一个新的

3.抽象类是单继承,多个接口是可以一个类来执行实现。

总结:抽象类是提取具体类的公因式,而接口是为了将一些不相关的类“杂凑”成一个共同的群体

只声明方法而不去实现它的类叫做抽象类。“高内聚,低耦合”简单的说,高内聚就是提高模块内部的关联程度,低耦合就是降低模块之间的关联程度.

用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创abstract 类的实例。然而可以创建一个变量,其类型是一个抽像类,并让它指向具体子类的一个实例。不能有抽像构造函数或抽像静态方法。Abstract 类的子类为它们父类中的所有抽像方法提供实现,否则它们也是抽像类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。

接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。

15. 数据库1表index和2个index有什么区别?

索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。

索引分为聚簇索引非聚簇索引两种,聚簇索引 是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。

建立索引的目的是加快对表中记录的查找排序。

根据数据库的功能,可以在数据库设计器中创建三种索引:唯一索引、主键索引和聚集索引

 唯一索引 唯一索引是不允许其中任何两行具有相同索引值的索引。

  当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在employee表中职员的姓(lname)上创建了唯一索引,则任何两个员工都不能同姓。

  主键索引

  数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。

  在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。

  聚集索引

  在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。

  如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。

创建索引  最普通的情况,是为出现在where子句的字段建一个索引。为方便讲述,先建立一个如下的表。

  CREATETABLEmytable(  idserial primary key,  category_id int not null default0,  user_id int not null default0,  adddate int not null default0  );

  如果在查询时常用类似以下的语句:

  SELECT * FROM mytable WHERE category_id=1;

  最直接的应对之道,是为category_id建立一个简单的索引:

  CREATE INDEX mytable_categoryid ON mytable (category_id);

  OK.如果有不止一个选择条件呢?例如:

  SELECT * FROM mytable WHERE category_id=1 AND user_id=2;

  第一反应可能是,再给user_id建立一个索引。不好,这不是一个最佳的方法。可以建立多重的索引。

  CREATE INDEX mytable_categoryid_userid ON mytable(category_id,user_id);

  注意到在命名时的习惯了吗?使用"表名_字段1名_字段2名"的方式。很快就会知道为什么这样做了。

  现在已经为适当的字段建立了索引,不过,还是有点不放心吧,可能会问,数据库会真正用到这些索引吗?测试一下就OK,对于大多数的数据库来说,这是很容易的,只要使用EXPLAIN命令:

  EXPLAIN

  SELECT * FROM mytable

  WHERE category_id=1 AND user_id=2;

  This is what Postgres 7.1 returns (exactlyasI expected)

  NOTICE:QUERY PLAN:

  Index Scan using mytable_categoryid_useridon

  mytable(cost=0.00..2.02 rows=1 width=16)

 

  EXPLAIN

  以上是postgres的数据,可以看到该数据库在查询的时候使用了一个索引(一个好开始),而且它使用的是创建的第二个索引。看到上面命名的好处了吧,马上知道它使用适当的索引了。

  接着,来个稍微复杂一点的,如果有个ORDERBY 子句呢?不管你信不信,大多数的数据库在使用orderby的时候,都将会从索引中受益。

  SELECT * FROM mytable

  WHERE category_id=1 AND user_id=2

  ORDER BY add date DESC;

  很简单,就象为where子句中的字段建立一个索引一样,也为ORDERBY的字句中的字段建立一个索引:

  CREATE INDEX mytable_categoryid_userid_adddate ON mytable (category_id,user_id,adddate);

  注意:"mytable_categoryid_userid_adddate"将会被截短为"mytable_categoryid_userid_addda"

  CREATE

  EXPLAIN SELECT * FROM mytable

  WHERE category_id=1 AND user_id=2

  ORDER BY add date DESC;

  NOTICE:QUERY PLAN:

  Sort(cost=2.03..2.03 rows=1 width=16)

  ->Index Scanusing mytable_categoryid_userid_addda

  onmytable(cost=0.00..2.02 rows=1 width=16)

  EXPLAIN

  看看EXPLAIN的输出,数据库多做了一个没有要求的排序,这下知道性能如何受损了吧,看来对于数据库的自身运作是有点过于乐观了,那么,给数据库多一点提示吧。

  为了跳过排序这一步,并不需要其它另外的索引,只要将查询语句稍微改一下。这里用的是postgres,将给该数据库一个额外的提示--在ORDERBY语句中,加入where语句中的字段。这只是一个技术上的处理,并不是必须的,因为实际上在另外两个字段上,并不会有任何的排序操作,不过如果加入,postgres将会知道哪些是它应该做的。

  EXPLAIN SELECT * FROM mytable

  WHERE category_id=1 AND user_id=2

  ORDER BY category_id DESC,user_id DESC,adddate DESC;

  NOTICE:QUERY PLAN:

  Index Scan Backward using

  mytable_categoryid_userid_add daon my table

  (cost=0.00..2.02 rows=1 width=16)

  EXPLAIN

  现在使用料想的索引了,而且它还挺聪明,知道可以从索引后面开始读,从而避免了任何的排序

数据库中主键与索引的区别(个人增加的知识)

区别:

1:主键是为了标识 数据库记录唯一性,不允许记录重复,且键值不能为空,主键也是一个特殊索引.

2:数据表中只允许有一个主键,但是可以有多个索引.

3.使用主键数据库会自动创建主索引,也可以在非主键上创建索引,方便查询效率.

4:索引可以提高查询速度,它就相当于字典的目录,可以通过它很快查询到想要的结果,而不需要进行全表扫描.

5: 主键索引外索引的值可以为空.

6:主键也可以由多个字段组成,组成复合 主键,同时主键肯定也是唯一索引.


7:唯一索引则表示该索引值唯一,可以由一个或几个字段组成,一个表可以有多个唯一索引.

HashIterator() {
    expectedModCount = modCount;
    if (size > 0) { // advance to first entry
    Entry[] t = table;
    while (index < t.length && (next = t[index++]) == null)
        ;
    }
}

  

猜你喜欢

转载自flylynne.iteye.com/blog/1636182
lv
今日推荐