• 面试题学习


       a left join b最多返回多少条记录,最少返回多少条记录?

          a left join b将返回a中所有的记录和b中符合on条件的记录。

          最少返回的记录数是a的记录数,这还是好理解的。

          最多返回的记录数a*b,如下:

          select * from a;

          id   name

          1    allen

          2    tim

          3    jackson

          select * from b;

          id    grade

          4    a

          5    b

          select a.id,a.name,b.grade from a left join b on a.id != b.id;返回的记录数是6条。

      PreparedStatement和Statement的区别

          应尽量使用PreparedStatement,可以防止SQL注入,例如:      

      mysql> select * from a where name = "abc" or 1=1--"";

      +------+--------  +

      | id  | name  |

      +------+--------  +

      |    1 | allen |

      |    2 | edison |

      |    3 | tim  |

      +------+--------+

      3 rows in set (0.00 sec)

       name字段输入的是:abc" or 1=1--",本应该查不到任何记录,结果却是查到了所有的记录。

         使用PreparedStatement做测试,查询到的结果是空,是不存在SQL注入的问题。PreparedStatement会先进行预编译,传递的参数会被当做字符串进行处理,这样就不会出现SQL拼接产生的问题。   

       String sql = "select * from a where name = ?";

       String paramter = "abc" or 1=1--"";

       Connection conn = null;

       PreparedStatement pstmt = null;

       ResultSet rs = null;

       try {

        conn = DBConnectionManager.getConnection();

        pstmt = conn.prepareStatement(sql);

        for (int i = 0; params != null && i < params.length; i++){

             pstmt.setString(i + 1, params[i]);

         }

            使用PreparedStatement还需要注意的一点是,在MySQL中,字段上如果有索引并且是varchar的,查询时不加引号,会导致为普通查询,索引会失效。反之,字段上如果有索引并且是int的,查询时加不加引号都是OK的。       

      mysql> explain select * from rcnetnode where index_in_mib = 10100001;

      +----+-------------+-----------+------+------------------+------+---------+------+------+-------------+

      | id | select_type | table     | type | possible_keys    | key  | key_len | ref  | rows | Extra       |

      +----+-------------+-----------+------+------------------+------+---------+------+------+-------------+

      |  1 | SIMPLE      | rcnetnode | ALL  | idx_index_in_mib | NULL | NULL    | NULL |  203 | Using where |

      +----+-------------+-----------+------+------------------+------+---------+------+------+-------------+

      1 row in set (0.00 sec)

      mysql> explain select * from rcnetnode where index_in_mib = "10100001";

      +----+-------------+-----------+------+------------------+------------------+---------+-------+------+-------------+

      | id | select_type | table     | type | possible_keys    | key              | key_len | ref   | rows | Extra       |

      +----+-------------+-----------+------+------------------+------------------+---------+-------+------+-------------+

      |  1 | SIMPLE      | rcnetnode | ref  | idx_index_in_mib | idx_index_in_mib | 203     | const |    2 | Using where |

      +----+-------------+-----------+------+------------------+------------------+---------+-------+------+-------------+

      1 row in set (0.00 sec)

          所以上面的代码中pstmt.setString(i + 1, params[i]);是没有问题的。

      HashMap实现的底层原理

          先从根源说起,对象的比较使用的是equals方法。比较字符串的内容用equals而不是==,是因为String类已经重写了equals,比较的是字符串的内容,而不是Object的比较内存地址。

          对象的比较重写equals方法的同时会重写hashcode方法,这是因为对象如果要放到hash类的集合(hashmap,hashset)中时,hashcode是对key进行散列的依据,决定了散列的效率。

         

           从上图我们可以发现HashMap是由数组+链表组成的,初始的容量是16,负载因子是0.75,即存储的元素超过12个时,容量自动扩充为32.元素存储的位置是key%16,比如31,31%16结果是15,(15,value)就在15的位置。

           

           HashMap对于上述的过程做了一些优化,不仅仅是key%16了。

           当调用put(key,value)时,首先获取key的hashcode,int hash = key.hashCode(); 
           再把hash通过一下运算得到一个int h. 
           hash ^= (hash >>> 20) ^ (hash >>> 12); 
           int h = hash ^ (hash >>> 7) ^ (hash >>> 4);

           再做index = h & (length-1),算出的index是(key,value)应在的位置,这样做会使index的分布尽量均匀。

           这点也是好理解的,如果hashcode写的不好,简单的key%16可能会使得个别链条很长,这样效率是较低的。

           HashSet的实现是用的HashMap的key。

        多线程模拟多个客户进行转账操作,有一个方法是转账,要求当转出金额大于账户余额时该线程放弃执行,将执行权力交给其他的线程。

            第一个反应是用yield,但是yield依赖于操作系统,不是最好的选择。

            正确的应是用notifyAll通知其他线程去继续执行,需要注意的是同步块锁得对象是this,下面是个例子程序。每个线程打印5个数字,将执 行权力交给其他的线程。

            使用notifyAll而不notify是因为notify更容易引起死锁而notifyAll则不会。      

    public class NotifyTest {
     public static void main(String[] args) {
      TestThread t = new TestThread();
      Thread t1 = new Thread(t);
      Thread t2 = new Thread(t);
      Thread t3 = new Thread(t);
      
      t1.start();
      t2.start();
      t3.start();
     }
    }
    
    class TestThread implements Runnable{
     int sum = 100;
     @Override
     public synchronized void run() {
      int localNum = sum;
      for(int i= sum;;){   
       if(i<= localNum -5){
        this.notifyAll();
        break;
       }else{
        System.out.println(Thread.currentThread().getName() + ":"+ i);
        i--;
        sum = i;
       }
      }  
     } 
    }
  • 相关阅读:
    DEM、DSM、DOM 名词解释
    html checkbox样式美化
    通过Ajax方式上传文件(input file),使用FormData进行Ajax请求
    C# 读取指定文件夹下所有文件
    ASP.NET 实现Base64文件流下载PDF
    Asp.Net使用百度编辑器(ueditor)
    asp.net 伪静态实现(UrlRewritingNet)
    C# 各种类型的转换
    asp.net操作word 配置在IIS上出现的问题
    plupload 上传组件的使用
  • 原文地址:https://www.cnblogs.com/lnlvinso/p/3937555.html
Copyright © 2020-2023  润新知