//第51题:统计一维数组中所有值出现的次数?返回一个数组,其元素的键名是原数组的值;键值是该值在原数组中出现的次数
$array=array(4,5,1,2,3,1,2,"a","a");

$ac=array_count_values($array);

/**
 * 输出结果:
 * Array(
 *   [4] => 1
 *   [5] => 1
 *   [1] => 2
 *   [2] => 2
 *   [3] => 1
 *   [a] => 2
 * )
 */
echo "<pre>";print_r($ac);

//第52题:如何统计字符串中每种字符的出现次数并排序?
function countStr($str){ 
 $str_array=str_split($str);//str_split()函数能将字符串中每个字符都转化为数组的元素 
 $str_array=array_count_values($str_array); 
 arsort($str_array);//arsort()函数对数组进行逆向排序并保持索引关系
 return $str_array;
} 
$str="asdfgfdas323344##$\$fdsdfg*$**$*$**$$443563536254fas";
/**
 * 输出结果:
 * Array(
    [$] => 7
    [3] => 6
    [*] => 6
    [4] => 5
    [f] => 5
    [s] => 4
    [d] => 4
    [5] => 3
    [a] => 3
    [6] => 2
    [2] => 2
    [g] => 2
    [#] => 2
  )
 */
echo "<pre>";print_r(countStr($str)); 

//第53题:str_word_count() 函数计算字符串中的单词数?

/**
 * 输出结果:2
 */
echo str_word_count("Hello world!");//参数二:默认0,返回单词的数目

/**
 * 输出结果:
   Array(
    [0] => Hello
    [1] => world
   )
 */
echo "<pre>";print_r(str_word_count("Hello world!",1));//参数二:1-返回包含字符串中的单词的数组

/**
 * 输出结果:
   Array(
    [0] => Hello
    [6] => world
   )
 */
echo "<pre>";print_r(str_word_count("Hello world!",2));//参数二:2-返回一个数组,其中的键是单词在字符串中的位置,值是实际的单词.

<?php
/**
 *  第56题:redis与memcached区别?
 *
 * 不同点:
 *
 *  (1)redis中并不是所有数据在有效期内只能常驻内存的(如果需要,可定期同步持久化到磁盘),这是和memcached相比一个最大的区别(memcached中的数据在有效期内是以键值对的形式常驻内存的)
 *  (2)redis不仅仅支持简单的键值对类型的数据,同时还提供list,set,hash等数据结构的存储;memcached仅支持简单的键值对类型的数据,但是memcached却可以缓存图片、视频等等数据
 *  (3)redis支持数据的备份,即master-slave模式的数据备份
 *  (4)redis支持数据的持久化和数据同步,可以将内存中的数据保存在磁盘中,重启系统后可以再次加载进行使用,缓存数据不会因此而丢失.memached缓存数据是常驻内存的,重启系统后数据就没了
 *  (5)redis可以通过expire设定有效期,memcached在set数据的时候可以指定要缓存的数据永不过期
 *  (6)redis可以做一主多从;memcached也可以做一主多从
 *  (7)redis当物理内存用完时,可以将一些很久没用到的value交换到磁盘;memcached当物理内存用完后就会自动清理一些早期的数据
 *
 * 相同点:
 *
 *  (1)redis和memcached都是将数据存放在内存中,都是内存数据库
 *  (2)redis和memcached都可以做一主多从
 *
 * 性能:
 *
 *  (1)redis根据其官方的测试结果:在50个并发的情况下请求10w次,写的速度是110000次/s,读的速度是81000次/s
 *  (2)redis将键名与值的最大上限各自设定为512MB;memcached则将键名限制在250字节,值也被限制在不超过1MB,且只适用于普通字符串.
 *
 *      何时使用memcached:
 *
 *  (1)小型静态数据:当我们需要缓存小型静态数据的时候可以考虑memcached,最具代表性的例子就是HTML代码片段;因为memcached的内部内存管理机制虽然不像redis的那样复杂,但却更具实际效率,这是因为memcached在处理元数据时所消耗的内存资源相对更少.作为memcached所支持的惟一一种数据类型,字符串非常适合用于保存那些只需要进行读取操作的数据,因为字符串本身无需进行进一步处理.
 *
 */
?>
 



<?php
//第57题:memcached的使用案例

//第一步:获取数据
function get_data(){
 $sql = "SELECT * from order_master ";//一般来说都是超级复杂的sql语句
 return $this->db->cache_all($sql);//获取缓存数据(如果缓存数据过期,则重新查询数据库并将查询到的数据放到memcache中并返回)
}

//第二步:获取memcache中缓存数据
public function cache_all($sql, $reload = false, $limit = null) {//参数1-sql语句、参数2-是否从数据库中重新获取数据并写入memcache、参数3-每次获取记录数量
 $this->reload = $reload;
 $sql = $this->get_query_sql($sql, $limit);//拼接sql语句,如:'select * from order_master limit 0,10'
 return $this->get_cache($sql, 'get_all');//参数1-拼接的sql、参数2-要执行的方法名;将sql语句作为参数调用get_all()方法
}

//第三步:从memcache中获取缓存数据 提示:1、如果缓存数据过期,则重新查询数据库并将查询结果放到memcache缓存中,返回数据. 2、如果缓存数据未过期,则直接获取缓存数据
protected function get_cache($sql,$method) {
 $cache_file = md5($sql.$method);//memcache中缓存数据的键名,格式:键名=md5(sql语句+方法名) 提示:一定要保证键名唯一
 $res = $this->cache->get($cache_file);//根据缓存数据的键名获取键值
 if(!$res) {//memcache中缓存数据过期的情况//如果memcache中缓存数据过期,则重新从数据库中获取数据,并将结果以键值对形式存储到memcache中
  $res= $this->$method($sql);//调用 $this->get_all($sql);//直接从数据库中获取数据并返回
  if($res && $this->cache_mark && !$this->reload) {
   $this->cache->set($cache_file, $res);//将数据库中查询到的数据以键值对形式set到memcache缓存中
  }
 }
 return $res;//返回数据
}

//第四步:直接从数据库中获取数据并返回
public function get_all($sql, $limit = null, $fetch_mode = MYSQLI_ASSOC) {
 $this->query($sql, $limit);
 $all_rows = array();
 $this->fetch_mode = $fetch_mode;
 while($rows = $this->fetch()) {
  $all_rows[] = $rows;
 }
 $this->free();
 return $all_rows;
}
?>

//第58题:文件缓存的使用案例
public function &get($key, $cache_time = '') {
  if(empty ($cache_time)) {
   $cache_time = $this->cache_time;//缓存时间
  } else {
   $cache_time = intval($cache_time);//缓存时间
  }
  $cache_encode_key  = $this->get_key($key);//获取一个唯一的长字符串
                //缓存文件的命名和缓存文件的存放位置
  $filename = $this->cache_dir.'/'.substr($cache_encode_key,0,2).'/'.substr($cache_encode_key,2,2).'/'.$cache_encode_key.".cache.php";
  if(!is_file($filename) || time() - filemtime($filename) > $cache_time) {//如果缓存文件不存在或者缓存文件过期,则返回false
   return false;
  } else {
   return unserialize(file_get_contents($filename));//如果缓存文件存在且未过期,那么读取缓存文件内容并返回
  }
 }
 public function set($key,$data) {
  $cache_encode_key  = $this->get_key($key);
  $cache_dir = $this->cache_dir.'/'.substr($cache_encode_key,0,2).'/'.substr($cache_encode_key,2,2).'/';//缓存文件的缓存目录
  $filename = $cache_dir.$cache_encode_key.".cache.php";//缓存文件名
  if( $this->mkpath($cache_dir) ) {//递归创建缓存目录
   $out    = serialize($data);//将要缓存的数据序列化
   file_put_contents($filename, $out);//将序列化的数据写入到缓存文件中
  }
 }
 public function add($key, $data) {
  $cache_encode_key = $this->get_key($key);
  $cache_dir = $this->cache_dir.'/'.substr($cache_encode_key,0,2).'/'.substr($cache_encode_key,2,2).'/';//缓存目录
  $filename = $cache_dir.$cache_encode_key.".cache.php";//缓存文件名
  if(is_file($filename)) {//如果缓存文件存在,则返回false
   return false;
  } else {//如果缓存文件不存在,则生成一个新的缓存文件到缓存目录
   $this->set($key, $data);
  }
 }
 public function del($key) {
  $cache_encode_key = $this->get_key($key);
  $cache_dir = $this->cache_dir.'/'.substr($cache_encode_key,0,2).'/'.substr($cache_encode_key,2,2).'/';//缓存目录
  $filename = $cache_dir.$cache_encode_key.".cache.php";//缓存文件名
  if(is_file($filename)) {//如果缓存文件存在则返回false
   return false;
  } else {//如果缓存文件不存在,则删除缓存文件
   @unlink($filename);
  }
 }

        public function get_key($key){
                return md5(CACHE_KEY.$key);//md5加密字符串
        }

//第59题:redis使用案例
//推送活动商品上线

    public function push_activity_goods_online($data) {
        $key = sprintf($this->config->item('activity_goods_push_key'), $data['goods_id']);

        $this->cache->redis->delete($key);
        $this->load->driver('cache', array('adapter' => 'redis'));
        return $this->cache->redis->hmset($key, $data);
    }

    //拉取上线活动商品

    public function pull_activity_goods_online($key) {
        $key = sprintf($this->config->item('activity_goods_push_key'), $key);
        $this->load->driver('cache', array('adapter' => 'redis'));

        return $this->cache->redis->hgetall($key);
    }

    //删除上线的活动商品

    public function del_activity_goods_online($key) {
        $key = sprintf($this->config->item('activity_goods_push_key'), $key);
        $this->load->driver('cache', array('adapter' => 'redis'));
        return $this->cache->redis->delete($key);
    }

    //推送活动上线

    public function push_activity_online($data) {

        $activity_push_key = $this->config->item('activity_push_key');
        //非通用平台作用哉活动,活动前缀+平台作用域
        if (isset($data['plateform']) && ($data['plateform']) != 'all') {
            $activity_push_key = $data['plateform'] . ':' . $activity_push_key;
        }

        //订单促销
        if ($data['activity_range'] == 1) {
            $key = sprintf($activity_push_key, 'order');
        } else {
            $key = sprintf($activity_push_key, $data['activity_id']);
        }

        $this->cache->redis->delete($key);
        $this->load->driver('cache', array('adapter' => 'redis'));
        return $this->cache->redis->hmset($key, $data);
    }

    //拉取上线活动

    public function pull_activity_online($key) {
        if ($key == 'order') {
            $key = sprintf($this->config->item('activity_push_key'), 'order');
        }if ($key == 'mobile:order') {
            $key = "mobile:" . sprintf($this->config->item('activity_push_key'), 'order');
        } else {
            $key = sprintf($this->config->item('activity_push_key'), $key);
        }

        $this->load->driver('cache', array('adapter' => 'redis'));

        return $this->cache->redis->hgetall($key);
    }

    //删除上线的活动

    public function del_activity_online($key, $activity = array()) {
        $activity_push_key = $this->config->item('activity_push_key');

        //非通用平台作用哉活动,活动前缀+平台作用域
        if (isset($activity['plateform']) && ($activity['plateform']) != 'all') {
            $activity_push_key = $activity['plateform'] . ':' . $activity_push_key;
        }
        $key = sprintf($activity_push_key, $key);
        $this->load->driver('cache', array('adapter' => 'redis'));
  //echo "redis->delete:" . $key . "\r\n<br>";
        return $this->cache->redis->delete($key);
    }

    //获取全部活动
    public function pull_all_activity_online() {
        $aids = array();
        $key = "*" . sprintf($this->config->item('activity_push_key'), "*");
        $this->load->driver('cache', array('adapter' => 'redis'));
        $hashname = $this->cache->redis->keys($key);
        if (is_array($hashname)) {
            $prefix_key = str_replace("%s", '', $this->config->item('activity_push_key'));
            foreach ($hashname as $key => $value) {
                /* if ($value == ($prefix_key . "order")) {
                  continue;
                  } */
                $aid = str_replace($prefix_key, "", $value);
                $aids[] = $aid;
            }
            return $aids;
        } else {
            return null;
        }
    }

    //获取所有活动商品
    public function pull_all_activity_goods_online() {
        $aids = array();
        $key = sprintf($this->config->item('activity_goods_push_key'), "*");
        $this->load->driver('cache', array('adapter' => 'redis'));
        $hashname = $this->cache->redis->keys($key);
        if (is_array($hashname)) {
            $prefix_key = str_replace("%s", '', $this->config->item('activity_goods_push_key'));
            foreach ($hashname as $key => $value) {
                $aid = str_replace($prefix_key, "", $value);
                $aids[] = $aid;
            }
            return $aids;
        } else {
            return null;
        }
    }

    //获取线上活动商品by goods_id
    public function get_activity_goods_online($product_id) {
        if (empty($product_id)) {
            return false;
        }
        $activity_goods = $this->pull_activity_goods_online($product_id);

        if (!empty($activity_goods)) {
            return $activity_goods;
        }

        return false;
    }

//第60题:php如何读取php.ini配置文件中的配置选项的值
echo ini_get('post_max_size');//获取上传文件的最大尺寸
echo get_cfg_var('post_max_size');//获取上传文件的最大尺寸

//第61题:php中如何动态的调用一个函数
$name_list = '小强,张三,李四,王五,马六';
$funName = 'explode';//函数名当作字符串
echo "<pre>";print_r($funName(',',$name_list));
echo "<pre>";print_r(call_user_func_array($funName,array(',',$name_list)));

/**
 * 结果:
 * Array(
 *  [0] => 小强 
 *  [1] => 张三
 *  [2] => 李四
 *  [3] => 王五
 *  [4] => 马六
 * )
 *
 * Array(
 *  [0] => 小强
 *  [1] => 张三 
 *  [2] => 李四
 *  [3] => 王五
 *  [4] => 马六
 * )
 */

/**
 *第62题:__call是魔术方法
 *  __call是魔术方法是指请求的方法不存在的时候采用的哪种处理方式;如果请求的方法名存在(跟参数列表无关),则不会调用此魔术方法
 */
class MethodTest {
  /**
   * 再如:
   *    public function __call($funName, $args){//参数1-要调用的方法名   参数2-传递给要调用方法的参数列表
   *    switch (count($args)) {
   *     case 0:
   *      return $this->$funName();
   *     case 1:
   *      return $this->$funName($args[0]);
   *     case 2:
   *      return $this->$funName($args[0], $args[1]);
   *     case 3:
   *      return $this->$funName($args[0], $args[1], $args[2]);
   *     case 4:
   *      return $this->$funName($args[0], $args[1], $args[2], $args[3]);
   *     case 5:
   *      return $this->$funName($args[0], $args[1], $args[2], $args[3], $args[4]);
   *     default:
   *      return call_user_func_array($this->$funName, $args);
   *    }
   *  }
   */
     public function __call($name,$arguments) {//参数1-调用的方法名 参数2-传递给调用方法的参数列表
  if(method_exists($this,$name)){
   return $this->$name();
  }else{ 
   echo "调用的方法 $name() 不存在;传递给 $name() 方法的参数列表如下:".implode(',',$arguments)."\n";
  }
     }
}
$obj = new MethodTest();
//结果:调用的方法 runTest() 不存在;传递给 runTest() 方法的参数列表如下:李四,张三 
$obj->runTest('李四','张三');//方法名、参数列表

//第63题:php.ini配置文件的解析

    (1)如:配置文件 test.ini

        [names]
        me = Robert
        you = Peter

        [urls]
        first = "http://www.example.com"
        second = "http://www.w3school.com.cn"

    (2)代码:<?php   print_r(parse_ini_file("test.ini"));   ?>

       结果:
            Array(
                [me] => Robert
                [you] => Peter
                [first] => http://www.example.com
                [second] => http://www.w3school.com.cn
            )

    (3)代码:<?php   print_r(parse_ini_file("test.ini",true));   ?>

       结果:
            Array(
                [names] => Array(
                    [me] => Robert
                    [you] => Peter
                )
                [urls] => Array(
                    [first] => http://www.example.com
                    [second] => http://www.w3school.com.cn
                )
            )

<?php
/** 
 * 第65题:php中的重写与重载
 * 首先来了解两个概念:
 *  重写/覆盖: 指子类重写了父类的同名方法,               发生在子类于父类之间 
 *  重载:  指本类中存在多个同名方法,但参数类型/个数不同,当传不同的参数时调用不同的方法   发生在本类内部 
 * PHP中,不允许存在多个同名方法. 因此,不能够完成java,c++中的这种重载;但是,PHP的灵活,可以模拟达到类似的效果 
*/

class human{
   public function say($name){
   echo $name,' 吃了吗?<br />';
   }
}

class stu extends human{

   /*
    * 报错:Fatal error: Cannot redeclare stu::say() in D:\wamp\www\php\61.php on line 28,因为在PHP中,不允许存在多个同名方法,没有重载概念这一说。
    * public function say($a,$b,$c){
    *  echo '哥仨好';
    * }
   */
   public function say(){
   echo '切克闹,卡猫百比<br />';
   }

}

$li=new stu();
$li->say();//结果:切克闹,卡猫百比;
$li->say('binghui');//结果:切克闹,卡猫百比;上面这个过程叫重写



//在PHP中模拟重载的方法
class Calc { 
    public function area() { 
        //判断一个调用area时,得到的参数个数 
        $args = func_get_args();//获取参数个数 
        if(count($args) == 1) { 
            return 3.14 * $args[0] * $args[0]; 
        } else if(count($args) == 2) { 
            return $args[0] * $args[1]; 
        } else { 
            return '未知图形'; 
        } 
    } 
} 
$calc = new Calc(); 
//计算圆的页面 
echo $calc->area(10),'<br />'; 
//计算矩形的面积 
echo $calc->area(5,8);
?>

<?php
/**
   第66题:static静态局部变量(不是数组)在函数中的使用特点:

   (1)静态局部变量不会随着函数的调用和退出而发生变化;

      不过,尽管该变量还继续存在,但确不能在函数外部直接使用它(获取不到值).

      倘若再次调用定义它的函数时,它又可继续使用,而且保存了前次被调用后留下的值.

   (2)静态局部变量只会初始化一次.

   (3)静态局部变量只能被初始化为一个字符值或一个常量,不能使用表达式.

      即使静态局部变量定义时没有赋初值,系统会自动赋初值0.

   (4)当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量.

   (5)static $var=5;//【变量的赋值操作只会在变量第一次初始化时会被调用,在之后函数的执行过程中该操作不会被调用】

   (6)静态变量是只存在于函数作用域的变量,不过,在函数执行完成后,这种变量的值不会丢失,

      也就是说,在下一次调用这个函数时,变量仍然会记得原来的值.

   要将某个变量定义为静态的,只需要在变量前加上static关键字即可

 */
function test(){
    static $var=5;  //static $var = 1+1;就会报错,不能使用表达式
    $var++;
    echo $var.'<br/>';
}

test(); //结果:6
test(); //结果:7
test(); //结果:8
echo $var;//Notice:Undefined variable: var 即:不能在函数外部使用静态局部变量,获取不到值


/**
  类中的static静态属性和方法用什么作用?

 (1)无论你实例化了多少个对象,static定义的属性和方法,都只有一个,只占有一次内存,节省了系统的内存开销

 (2)访问static属性和方法时,只能用::访问

 (3)静态成员是一种类变量,可以把它看成时属于整个类而不是属于类的某个实例。

    与一般的实例变量不同的是,静态成员只保留一个变量值,而这个变量值对所有的实例都是有效的

    也就是说,所有的实例共享这个成员

 (4)$this只表示类的当前实例,

    self::表示的是类本身,在类之外的代码中不能使用这个操作符,而且它不能识别自己在继承树层次结构中的位置。

    也就是说,在扩展类中使用self作用域时,self可以调用基类中声明的方法,但它调用的总是已经在扩展类中重写的方法。

    与$this不同的是,在使用静态变量时,必须在作用域限定符后面加上$符号

    如:
   $this->name;//调用非静态属性

   self::$name;//调用静态属性

 (5)扩展类中,在基类的方法被重写的情况下,使用 parent 作用域调用定义在基类中的方法。

    静态成员也可以只属于父类。如果在子类和父类中同时声明了某个成员,也可以使用parant::在子类中访问父类中的变量。

    在这种情况下,父类的静态成员和子类的静态成员保存的是不同的值

 (6)可以在::操作符的左边写上类的名称来静态地访问某个成员,这样避免创建类的实例.

    不仅可以省略掉实例化类的代码,而且还会更高效,因为类的每个实例都会占用一小部分的系统资源

 (7)案例:

  <?php
   class visitors{
    private static $visitors = 0;
    function __construct()
    {
      self::$visitors++;
    }
    static function getVisitors()
    {
     return self::$visitors;
    }
   }
   $visits = new visitors();
   echo visitors::getVisitors()."<br />";//结果:1
   $visits2 = new visitors();
   echo visitors::getVisitors()."<br />";//结果:2
  ?>

  因为$visitors字段声明为static,所以对其值的任何改变都会反映到所有实例化对象中。

  还要注意,静态字段和方法应使用self关键字和类名来引用,而不是通过this和箭头操作符。

  这是因为使用“正常”方法引用静态字段是不可能的,会导致语法错误。

  不能在类中使用$this来引用为static字段

 (8)静态方法:

  静态方法和非静态方法之间有一个重要的区别:在调用静态方法时,不再需要拥有类的实例。

  静态方法和非静态方法使用原则:

   (1)、是如果某个方法中不包含$this变量,就应该时静态方法;

   (2)、如果不需要类的实例,可能还应该使用静态类,这样可以免去实例化类的工作。

   (3)、在静态方法中时不能使用$this变量的,因为静态方法不属于某个特定的实例。
 */

?>

Java自动装箱与拆箱的深入分析

??自动装箱与拆箱机制在骨子里运用中十三分广泛,可是也特地轻易出错,博主在直面上面一道题的时候自信满满,可仍然未有能够全对,所以写下这篇博文,给本身对电动装箱与拆箱机制做一下文化加强,也给各位朋友做一下参阅。
??首先有如此一道题,给出上面代码的出口结果:

public class AutoBoxing
{
    public static void main(String[] args)
    {
        Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Integer d = 3;
        Integer e = 321;
        Integer f = 321;
        Long g = 3L;

        System.out.println(c==d);
        System.out.println(e==f);
        System.out.println(c==(a+b));
        System.out.println(c.equals(a+b));
        System.out.println(g==(a+b));
        System.out.println(g.equals(a+b));
    }
}

??运行结果:

true
false
true
true
true
false

??倘让你看看此间,答案都没有错,而且从不丝毫的疑云,那么对于你的话那篇博文就此停止了,借使未有,请继续读书。


??首先从最基础的始发讲起,首先通过反编写翻译来看一看自动装箱和拆箱的进度:
??首先看如下一段程序:

public class AutoBoxing2
{
    public static void main(String[] args)
    {
        Integer a = 1;
        Integer b = 2;
        Integer c = a+b;
    }
}

??反编写翻译结果为:(假设对于java反编写翻译不太了然的意中人能够先看一下《通过Java反编写翻译报料一些主题素材的本来面目》)

public jvm.optimize.AutoBoxing2();
    flags: ACC_PUBLIC

    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #1                  // Method java/lang/Object."":()V
         4: return        
      LineNumberTable:
        line 3: 0

  public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC

    Code:
      stack=2, locals=4, args_size=1
         0: iconst_1      
         1: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
         4: astore_1      
         5: iconst_2      
         6: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
         9: astore_2      
        10: aload_1       
        11: invokevirtual #3                  // Method java/lang/Integer.intValue:()I
        14: aload_2       
        15: invokevirtual #3                  // Method java/lang/Integer.intValue:()I
        18: iadd          
        19: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        22: astore_3      
        23: return        
      LineNumberTable:
        line 8: 0
        line 9: 5
        line 10: 10
        line 11: 23

??能够看来Integer a=1实际上自动装箱为Integer a =
Integer.valueOf(1),而在拓展a+b的时候能够看看进展了全自动拆箱,将a拆箱为Integer.intValue();然后将a和b的int值相加,相加之后有进行了机动装箱:Integer
c=Integer.valueOf(3).


??接下去大家就足以上边标题中付出的
System.out.println(c==d);和System.out.println(e==f);他们各自的结果为true和false。
??知道Integer会缓存-128至127的意中人估量这两条语句的出口结果都能答应。
??假若没有答应,请看深入分析:
??Integer c=3;会自行装箱为Integer c =
Integer.valueOf(3),那么看一下valueOf方法的源码:

public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }

??能够见到实际Integer会缓存-128值127的剧情,假设值在那些区间之内(比方c和d),那么就能回去IntegerCache中的引用,所以Integer
c= Integer d = IntegerCache.cache[3+(–128)] =
IntegerCache.cache[131], c和d是万分的。
??然则如果抢先这一个区间,举例e和f,则Integer e = new Integer(321);
Integer f = new
Integer(321);new出来的当然是在堆中新开拓的内部存款和储蓄器,两份地址不相同,自然e和f不相同,也正是假设遇到这么的情形:

Integer m = new Integer(2);
Integer n = new Integer(2);
System.out.println(m==n);

??那么输出的结果是false(假设Integer m=2; Intger n=2则m和n一样)


??接着再说System.out.println(c==(a+b));
??大家看如下代码:

Integer a = 1;
Integer b = 2;
Integer c = 3;
System.out.println(c==(a+b));

??反编写翻译之后:

          0: iconst_1      
         1: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
         4: astore_1      
         5: iconst_2      
         6: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
         9: astore_2      
        10: iconst_3      
        11: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        14: astore_3      
        15: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        18: aload_3       
        19: invokevirtual #4                  // Method java/lang/Integer.intValue:()I
        22: aload_1       
        23: invokevirtual #4                  // Method java/lang/Integer.intValue:()I
        26: aload_2       
        27: invokevirtual #4                  // Method java/lang/Integer.intValue:()I
        30: iadd          
        31: if_icmpne     38
        34: iconst_1      
        35: goto          39
        38: iconst_0      
        39: invokevirtual #5                  // Method java/io/PrintStream.println:(Z)V
        42: return    

??能够观望实际在c==(a+b)的时候是施行拆箱机制,实际上正是在运算3==2+1,当然便是true咯。


??继续注明: System.out.println(c.equals(a+b));
??一样看一下c.equals(a+b)反编写翻译的结果(篇幅限制,只截取部分连锁的结果):

        19: aload_1       
        20: invokevirtual #4                  // Method java/lang/Integer.intValue:()I
        23: aload_2       
        24: invokevirtual #4                  // Method java/lang/Integer.intValue:()I
        27: iadd          
        28: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        31: invokevirtual #5                  // Method java/lang/Integer.equals:(Ljava/lang/Object;)Z

??能够见见a+b先拆箱为int再相加之后再装箱为Integer型与c进行equals相比,那么大家再看一下equals()方法的源码:

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

??通过查看源码可见此条语句的出口结果为true。


??最终来看一下System.out.println(g==(a+b));和System.out.println(g.equals(a+b));两条语句。
??System.out.println(g==(a+b));由后面包车型客车推论可见最终g拆箱为long型,a+b为int型,基础项目int能够自行进级为long,所以输出为true。
??对于System.out.println(g.equals(a+b));能够看一下Long的equals()方法。

    public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
    }

??对于(a+b)来讲是Integer类型,所以回来false.
??鉴于包装类的“==”运算在不境遇算术运算的事态下不会自行拆箱,以及它们equals()方法不管理数量转型的涉及,博主建议在其实编码中要尽量幸免那样使用机动装箱与拆箱机制。

 

 

??自动装箱与拆箱机制在其实使用中丰富普及,不过也特意轻松出错,博主在直面下边一道题的时候自信满满,可…

前言:年初了,骚年们有未有很鸡冻——年初奖有相当的大概率了。此前在介绍事件的那篇 C#基本功体系——再也不用忧郁面试官问作者“事件”了 也谈起了面试,引起了成都百货上千园友的共鸣。在不久的年后,火爆的跳槽季快要来了,假如你准备换工作,本篇或多或少能帮到你;借使您不准备换,没提到,看看也无妨,看看是或不是有那么几道题能够唤起您的一丝丝催人泪下;又只怕您是面试官,老实交代,是或不是问过里面的少数无论是你是还是不是妄想面试,用一句自嘲的话来讲:专门的学业经历能够没有,但换职业的阅历咱可不能够缺

第67题:session机制:

对于一些基础的笔试和轻巧的面试题,博主就不一板一眼了,新浪一搜一大把:http://zzk.cnblogs.com/s?t=b&w=.net
面试题。本篇就重组博主遭遇以及英特网时不经常见到的片段面试题做二个计算。PS:由于博主用的首要性编制程序语言是C#,所以本篇主要介绍关于.net面试中的常见难点。

<?php

    /**
     * 【session.save_handler = files】:默认的session处理机制
     *      (1)session_start()是session机制的开始,它有一定概率开启垃圾回收,因为session是存放在文件中,PHP自身的垃圾回收是无效的,SESSION的回收是要删文件的,这个概率是根据php.ini的配置决定的,
               但是有的系统是 session.gc_probability = 0,这也就是说概率是0,而是通过cron脚本来实现垃圾回收
                session.gc_probability = 1  //垃圾回收机制
                session.gc_divisor = 1000   //垃圾回收机制
                session.gc_maxlifetime = 1440//过期时间 默认24分钟
                //垃圾回收的几率为:session.gc_probability/session.gc_divisor,即:1/1000, 
                //不建议设置过小,因为session的垃圾回收,是需要检查每个文件是否过期的。
                session.save_path = //好像不同的系统默认不一样,有一种设置是 "N;/path"
                //这是随机分级存储,这个样的话,垃圾回收将不起作用,需要自己写脚本

     *      (2)session会判断当前是否有$_COOKIE[session_name()];session_name()返回保存session_id的COOKIE键值;这个值可以从php.ini找到,session.name = PHPSESSID //默认值PHPSESSID
     *      (3)如果不存在会生成一个session_id,然后把生成的session_id作为COOKIE的值传递到客户端;相当于执行了下面COOKIE 操作,注意的是,这一步执行了setcookie()操作,COOKIE是在header头中发送的,
     *         这之前是不能有输出的,PHP有另外一个函数 session_regenerate_id() 如果使用这个函数,这之前也是不能有输出的
                setcookie(
                          session_name(),//PHPSESSID,对应php.ini中session.name = PHPSESSID配置选项
                          session_id(),  //生成的session_id值
                          session.cookie_lifetime,//默认0
                          session.cookie_path,//默认'/'当前程序跟目录下都有效
                          session.cookie_domain,//默认为空
                )
     *      (4)如果存在session_id,那么session_id = $_COOKIE[session_name];然后去session.save_path指定的文件夹里去找名字为'SESS_'. session_id()的文件,读取文件的内容反序列化,然后放到$_SESSION中
     *      (5)为$_SESSION赋值:
     *         比如新添加一个值$_SESSION['test'] = 'blah';那么这个$_SESSION只会维护在内存中,当脚本执行结束的时候,会把$_SESSION的值写入到session_id指定的文件夹中,然后关闭相关资源
               这个阶段有可能执行更改session_id的操作,比如销毁一个旧的的session_id,生成一个全新的session_id.
               if (isset($_COOKIE[session_name()])) {//如:匿名用户有一个SESSION的,当它登录后需要换用新的session_id
                    setcookie(session_name(), '', time() - 42000, '/');//旧session cookie过期
               }
               session_regenerate_id();//这一步会生成新的session_id,此时再通过session_id()返回的是新的值
     *      (6)写入SESSION:在脚本结束的时候会执行SESSION写入操作,把$_SESSION中值写入到session_id命名的文件中,可能已经存在,可能需要创建新的文件
     *      (7)销毁SESSION:SESSION发出去的COOKIE一般属于即时COOKIE,保存在内存中,当浏览器关闭后,才会过期,假如需要人为强制过期,比如 退出登录,而不是关闭浏览器,那么就需要在代码里销毁SESSION,方法有很多:
               setcookie(session_name(), session_id(), time() - 8000000, ..);//退出登录前执行
               usset($_SESSION);//这会删除所有的$_SESSION数据,刷新后,有COOKIE传过来,但是没有数据
               session_destroy();//这个作用更彻底,删除$_SESSION 删除session文件,和session_id
     *
     * 【session.save_handler = user】:用户自定义session处理机制
     *      (1)用户自定义session处理机制:session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc');//【执行此函数将修改session默认的存储介质;修改是隐式的,所以不会体现在php.ini配置文件中的session.save_handler配置项】
               session_start():
                    执行open($save_path, $session_name)打开session操作句柄,$save_path 在session.save_handler = files的情况下它就是session.save_path;但是如果用户自定的话,这个两个参数都用不上,直接返回TRUE
                    执行read($id)从中读取数据.//【这个参数是自动传递的就是session_id()】,可以通过这个值进行操作
            (2)脚本执行结束:执行write($id, $sess_data) //两个参数,很简单
            (3)假如用户需要session_destroy(),先执行destroy.在执行第2步
            (4)案例:
                <?php
                //SESSION初始化的时候调用
                function open($save_path, $session_name){
                        global $sess_save_path;
                        $sess_save_path = $save_path;
                        return(true);
                }

                //关闭的时候调用
                function close(){
                        return(true);
                }

                function read($id){//【参数会自动传递,就是session_id()】
                        global $sess_save_path;
                        $sess_file = "$sess_save_path/sess_$id";
                        return (string) @file_get_contents($sess_file);
                }

                //脚本执行结束之前,执行写入操作
                function write($id, $sess_data){//【参数会自动传递,就是session_id()】
                        echo "sdfsf";
                        global $sess_save_path;

                        $sess_file = "$sess_save_path/sess_$id";
                        if ($fp = @fopen($sess_file, "w")) {
                          $return = fwrite($fp, $sess_data);
                          fclose($fp);
                          return $return;
                        } else {
                          return(false);
                        }

                }

                function destroy($id){//【参数会自动传递,就是session_id()】
                        global $sess_save_path;

                        $sess_file = "$sess_save_path/sess_$id";
                        return(@unlink($sess_file));
                }

                function gc($maxlifetime){
                        global $sess_save_path;

                        foreach (glob("$sess_save_path/sess_*") as $filename) {
                          if (filemtime($filename) + $maxlifetime < time()) {
                            @unlink($filename);
                          }
                        }
                        return true;
                }
                ?>
     *
     */


    //【session.save_handler = user】:用户自定义session处理机制
    $SESS_DBHOST = "127.0.0.1";  
    $SESS_DBNAME = "cms";   
    $SESS_DBUSER = "root";  
    $SESS_DBPASS = "";   

    $SESS_DBH = ""; //数据库连接句柄  
    $SESS_LIFE = get_cfg_var("session.gc_maxlifetime");//默认:8M

    //SESSION初始化的时候调用
    function sess_open($save_path, $session_name) {   
        global $SESS_DBHOST, $SESS_DBNAME, $SESS_DBUSER, $SESS_DBPASS, $SESS_DBH;   

        if (! $SESS_DBH = mysql_pconnect($SESS_DBHOST, $SESS_DBUSER, $SESS_DBPASS)) {   
            echo "<li>Can't connect to $SESS_DBHOST as $SESS_DBUSER";   
            echo "<li>MySQL Error: " . mysql_error();   
            die;   
        }   

        if (! mysql_select_db($SESS_DBNAME, $SESS_DBH)) {   
            echo "<li>Unable to select database $SESS_DBNAME";   
            die;   
        }   

        return true;   
    }   

    //关闭的时候调用
    function sess_close() {   
        return true;   
    }   

    function sess_read($key) {   
        global $SESS_DBH, $SESS_LIFE;   

        $qry = "SELECT value FROM session_tbl WHERE sesskey = '$key' AND expiry > " . time();   
        $qid = mysql_query($qry, $SESS_DBH);   

        if (list($value) = mysql_fetch_row($qid)) {   
            return $value;   
        }   

        return false;   
    }   

    //脚本执行结束之前,执行写入操作
    function sess_write($key, $val) {   
        global $SESS_DBH, $SESS_LIFE;   

        $expiry = time() + $SESS_LIFE; //过期时间   
        $value = addslashes($val);   

        $qry = "INSERT INTO session_tbl VALUES ('$key', $expiry, '$value')";   
        $qid = mysql_query($qry, $SESS_DBH);   

        if (! $qid) {   
            $qry = "UPDATE session_tbl SET expiry = $expiry, value = '$value' WHERE sesskey = '$key' AND expiry > " . time();   
            $qid = mysql_query($qry, $SESS_DBH);   
        }   

        return $qid;   
    }   

    function sess_destroy($key) {   
        global $SESS_DBH;   

        $qry = "DELETE FROM session_tbl WHERE sesskey = '$key'";   
        $qid = mysql_query($qry, $SESS_DBH);   

        return $qid;   
    }   

    function sess_gc($maxlifetime) {   
        global $SESS_DBH;   

        $qry = "DELETE FROM session_tbl WHERE expiry < " . time();   
        $qid = mysql_query($qry, $SESS_DBH);   

        return mysql_affected_rows($SESS_DBH);   
    }   

    //【session.save_handler = user】:用户自定义session处理机制主要是通过session_set_save_handler()来进行协调执行
    //【执行此函数将修改session默认的存储介质;修改是隐式的,所以不会体现在php.ini配置文件中的session.save_handler配置项】
    session_set_save_handler(   
        "sess_open",    //可以进行重写
        "sess_close",   //可以进行重写
        "sess_read",    //可以进行重写
        "sess_write",   //可以进行重写
        "sess_destroy", //可以进行重写  
        "sess_gc"       //可以进行重写
    );   
    session_start();    //除了以上被重写的session函数外,其它的session函数还是想以前一样调用
    ?>

一、对于 Web 质量优化,您有何精通和经验吗?

出现指数:五颗星

关键考试的地方:那道题是博主在新浪的资源新闻里面来看的,回看此前年的面试经历,发掘此题出现概率依旧比较高的。因为它的考面灰常广,可以让面试官异常快明白您的技艺涉及面以及那些技艺面的深浅。

参考答案:这些难题得以分前端和后端来讲。

1、前端优化

(1)收缩 HTTP 必要的次数。大家知道每一遍发送http央浼,建设构造连接和等候相应会花去10%部分时光,所以在殡葬http央浼的时候,尽量收缩诉求的次数,三回呼吁能抽取的多少就无须分多次出殡和埋葬。

(2)启用浏览器缓存,当显著须求的多少不会发生变化时,能够直接读浏览器缓存的就不要向服务端发送央浼。比如我们ajax里面有二个参数能够设置须要的时候是否启用缓存,这种场合下就需求大家在出殡和埋葬须求的时候做好相应的缓存管理。

(3)css文件放在

中间,js文件尽量放在页面包车型地铁最底层。因为央求js文件是很花费时间,假若身处里面,就能形成页面包车型地铁DOM树显示要求静观其变js文件加载成功。那也等于为啥许多网址的源码里面看到引用的文本放在最终的缘由。

(4)使用压缩的css和js文件。这么些不用多说,网络流量小。

(5)假设条件允许,尽量采用CDN的办法引用文件,那样就可以减小互连网流量。举个例子我们常用的网址http://www.bootcdn.cn/。

(6)在写js和css的语法时,尽量防止重复的css,尽量收缩js里面循环的次数,诸如此类。

2、后端优化:

(1)程序的优化:那是多少个相当大的话题,小编这里就选多少个科学普及的。比如裁减代码的层级结构、幸免循环嵌套、幸免循环CURAV4D数据库、优化算法等等。

(2)数据库的优化:(由于数据库优化不是焦点着重,所以可选多少个首要的来讲)比方启用数据库缓存、常用的字段建索引、尽量幸免大事务操作、幸免select
* 的写法、尽量不用in和not in 这种耗品质的用法等等。

(3)服务器优化:(这一个可看作可挑选)负载均衡、Web服务器和数据库分离、UI和Service分离等等。

第68题:PHP 的排放物回收机制:

二、MVC路由明白?(数见不鲜)

出现指数:五颗星

重在考试的场合:此题主要考试的地点是MVC路由的明白。

参照他事他说加以考查答案:

1、首先大家要清楚MVC中路由的功能:url
Routing的功用是将浏览器的U昂CoraL央求映射到一定的MVC调整器动作。

2、当大家访问

PHP垃圾回收机制是php5之后才有的这个东西,下面我来给大家介绍一下关于PHP垃圾回收机制一些理解,希望对各位同学有所帮助。

php 5.3之前使用的垃圾回收机制是单纯的“引用计数”,也就是每个内存对象都分配一个计数器,当内存对象被变量引用时,计数器 1;当变量引用撤掉后,计数器-1;当计数器=0时,表明内存对象没有被使用,该内存对象则进行销毁,垃圾回收完成。

“引用计数”存在问题,就是当两个或多个对象互相引用形成环状后,内存对象的计数器则不会消减为0;这时候,这一组内存对象已经没用了,但是不能回收,从而导致内存泄露;

php5.3开始,使用了新的垃圾回收机制,在引用计数基础上,实现了一种复杂的算法,来检测内存对象中引用环的存在,以避免内存泄露

三、谈谈你以为做的科学系统,大约介绍下用到了何等本领?

并发指数:五颗星

首要考试的地方:那是一道特别开放的面试题。博主碰着过一些家商厦的面试官都问道了那一个,博主认为他们是想经过这些标题飞速驾驭面试者的技巧水平。此题只要整合您近些日子项目用到的工夫谈谈就好了。

参谋答案:

就拿作者前面做过的一个类别为例来大概表明一(Wissu)下吗。项目分为客户端和服务端,客户端分成BS客户端和CS客户端,BS客户端应用MVC
5.0的框架,CS客户端是Winform项目,服务端使用WebApi统一提供劳务接口,思虑以往恐怕还要扩张手提式有线电话机端,所以服务接口的参数和再次来到值使用通用的Json格式来传递数据。

1、服务端采纳的面向接口编制程序,我们在软件架构的历程中,层和层之间通过接口依赖,下层不是一贯给上层提供实现,而是提供接口,具体的贯彻以注重注入的点子在运营的时候动态注入进来。MEF正是贯彻依赖注入的一种组件。它的施用使得UI层不直接依赖于BLL层,而是借助于中间的三个IBLL层,在程序运维的时候,通过MEF动态将BLL里面包车型地铁落实注入到UI层里面去,那样做的裨益是缩减了层与层之间的耦合。服务端的不行里面、权限验证、日志记录等通用成效利用了AOP拦截的编写制定统一保管,项目中选拔的是Postsharp那些组件,很好地将通用须要功用未有相关的类其中分离出来,提升了代码的可维护性。

2、BS的客户端应用的jquery+bootstrap
的不二等秘书技,全数页面使用流式布局,能更加好适应各样不相同的终端设备(PC、手机)。项目中动用了各样效用庞大的bootstrap组件,能适应各类繁复的事体须求。

版权注解:本文为博主原创文章,未经博主允许不得转载。

四、Js承接实现。

并发指数:五颗星

重在考场:那道题考验面试者对js精通的吃水。依照博主的经验,这种题一般在笔试出现的可能率非常的大,为何把它献身这里,因为它真的太宽广了。其实js完毕再而三的措施好些个,大家如果写好内部一种就好了。

参谋答案:原型链承袭

图片 1

function Person(name, age){
    this.name = name;
    this.age = age;
}    
//通过原型链给Person添加一个方法
Person.prototype.getInfo = function(){
    console.log(this.name + " is " + this.age + " years old!");
}


function Teacher(staffId){
    this.staffId = staffId;
}

//通过prototype生命Teacher继承Person
Teacher.prototype = new Person();

var will = new Teacher(1000);
will.name = "Will";
will.age = 28;
will.getInfo();

图片 2


五、谈谈你对设计格局的认知?结合您用得最多的一种设计形式说说它的使用。

出现指数:五颗星

主要考场:不用多说,那题考的就是对设计格局的知情。一般为了轻便可能会供给你写三个单例形式,注意最棒是写二个完好无损点的,思虑线程安全的这种。然后会让你说说你在等级次序中什么景况下会用到这种格局

参谋答案:

通用写法

图片 3

   public class Singleton
    {
        // 定义一个静态变量来保存类的实例
        private static Singleton uniqueInstance;

        // 定义一个标识确保线程同步
        private static readonly object locker = new object();

        // 定义私有构造函数,使外界不能创建该类实例
        private Singleton()
        {
        }

        /// 
        /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        /// 
        /// 
        public static Singleton GetInstance()
        {// 双重锁定只需要一句判断就可以了
            if (uniqueInstance == null)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建,否则直接返回
                    if (uniqueInstance == null)
                    {
                        uniqueInstance = new Singleton();
                    }
                }
            }
            return uniqueInstance;
        }
    }

图片 4

单例情势确认保障贰个类唯有三个实例,并提供三个大局访问点,它的行使情形例如职分管理器整个类别中应有唯有多少个把,再举个例子操作文件的对象,同一时间大家只好有二个指标去操作文件呢。最要害的,比如大家项目中用得相当多的效应→日志记录,在贰个线程中,记录日志的指标应该也只可以有四个吗。单例情势的目标是为了确认保障程序的安全性和数目标唯一性。只怕你也可以构成您利用的别的设计格局来注解。

六、IIS的干活规律?

并发指数:四颗星

关键考试的地点:此题重要考的是.net
framework和IIS是哪些构成显示页面包车型大巴。那是叁个某些复杂的进程,面试的时候不容许说得完全,那么大家就抓住多少个第一点说说就可以。其实博主也不可能一心知晓那些历程,明日刚刚借那些时机温习下。

参照他事他说加以考查答案:

1、当客户端发送HTTP
Request时,服务端的HTTP.sys(能够知晓为IIS的一个监听组件)
拦截到这几个诉求;

2、HTTP.sys 联系 WAS
向配置存款和储蓄宗旨呼吁配置消息。

3、然后将呼吁传入IIS的运用程序池。

4、检查乞请的后缀,运维aspnet_isapi.dll这几个dll,那一个dll是.net
framework里面包车型客车,也正是谈到这一步,央求进入了.net
framework的总理范围。

5、那一年假设是WebForm,开端实践复杂的页不熟悉命周期(HttpRuntime→ProcessRequest→HttpContext→HttpHandler);假使是MVC,则运转mvc的路由机制,依照路由规则为URAV4L来钦命HttpHandler。

6、httpHandler管理乞请后,伏乞停止,给出Response,客户端管理响应,整个经过甘休。

七、Http协议

并发指数:四颗星

根本考试的地方:此题首要考对于web里面http协议的掌握。

参考答案:

1、http协议是浏览器和服务器双方共同服从的规范,是一种基于TCP/IP应用层协议。

2、http是一种标准的央浼/相应协议。客户端发送伏乞,必要的原委以及参数存放到央浼报文里面,服务端收到须求后,做出相应,再次来到相应的结果放到相应报文里面。通过F12足以查阅央浼报文和对应报文。

3、http协议是”无状态”的,当客户端向服务端发送二遍http诉求后,服务端收到央浼然后回来给客户端相应的结果,服务器会马上断开连接并释放能源。在事实上开销进度中,大家临时须要“保持”这种场地,所以衍生出了Session/Cookie这几个技能。

4、http乞请的措施根本有get/post。

5、http状态码最佳记多少个,博主有叁遍面试就被问到了。200(需要成功)、404(哀告的财富不设有)、403(禁止访问)、5xx(服务端错误)

八、数据库优化经验(后端程序员非经常见)

出现指数:四颗星

重在考试的场面:此题调查后端程序员操作数据库的经历。说实话,数据库是博主的弱项,博主感觉对于这种考题,供给引发多少个常用并且首要的优化经验,假使说得极度,迎接大家斧正。

参谋答案:

1、数据库运转方面包车型地铁优化:启用数据库缓存。对于有个别相比较常用的询问能够选用数据库缓存的体制,安插的时候要求注意设置好缓存注重项,制止“过期”数据的产生。

2、数据库索引方面包车型地铁优化:譬喻常用的字段建索引,联合查询思虑共同索引。(PS:假使您有底蕴,可以敞开谈谈集中索引和非聚焦索引的施用处境和界别)

3、数据库查询方面包车型地铁优化:防止select *
的写法、尽量不用in和not in 这种耗品质的用法等等。

4、数据库算法方面包车型地铁优化:尽量制止大事务操作、减弱循环算法,对于大数据量的操作,制止使用游标的用法等等。

九、关于代码优化你怎么精通?你会考虑去代码重构吗?

并发指数:四颗星

关键考试的场地:此题考的是面试者对代码优化的驾驭,以及代码怎么样重构的相关知识。

参谋答案:

1、对于代码优化,在此之前的商城每一周会做代码调查,核实的器重职能便是确认保障代码的不利和实施作用,比方收缩代码的层级结构、幸免循环嵌套、防止循环CUPAJEROD数据库、尽量幸免二次收取多量数量放在内部存款和储蓄器中(轻易内部存储器溢出)、优化算法等。

2、对于陈旧代码,大概过多地点有调用,并且开荒和掩护人士很有不小希望不是同壹个人,所以重构时要杰出小心,假诺未有丰硕的握住,不要随便重构。假如必须求重构,必须做好丰富的单元测试和大局测试。

十、谈谈你的优点和缺陷?

出现指数:四颗星

最重要考场:那道题令人有一种骂人的冲动,不过不能够,偏偏好些个所谓的大厂家会问这么些。举个例子中兴。那么些标题差异,答案能够自个儿共青团和少先队。

参照他事他说加以考察答案:

优点:对于新的技巧学习能力强,能极快适应新条件等等

缺陷:对本领太过头执拗等等

十一、关于劳动器端 MVC 架构的本事完毕,您是怎么着明白的?这种框架结构格局有哪些受益?您在项目中是怎么行使这一架构的?

出现指数:三颗星

入眼考场:此题首要考的对于MVC这种框架的接头。

参照他事他说加以考察答案:MVC,看名称就会想到其意义,Model、View、Controller。全部的界面代码放在View里面,全体涉及和分界面交互以及U奥德赛L路由有关的逻辑都在Controller里面,Model提供数据模型。MVC的框架结构情势会让系统的可维护性更高,使得每一片段更加小心本身的职分,并且MVC提供了强有力的路由机制,方便了页面切换和分界面交互。然后能够构成和WebForm的相比,谈谈MVC怎么样化解复杂的控件树生成、怎样制止了复杂的页目生命周期。

十二、网址优化:网址运转慢,怎么样定位难题?开采难点怎样化解?

出现指数:三颗星

要害考试的场面:此题和难题一类似,考察Web的主题材料一定才干和优化方案。

参照他事他说加以调查答案:

浏览器F12→互连网→查看http诉求数以及各类诉求的耗费时间,找到难题的来自,然后逐条化解,化解方案能够参照他事他说加以侦察难题一里面包车型地铁Web优化方案。

十三、说说你最拿手的技艺?并说说您是如何运用的?

并发指数:三颗星

重在考试的地方:那是一道非常开放的面试题。最初境遇这种难点,博主很想来一句:你妹,那叫什么难点!但真的有面试官问到。回头想想,其实此题侦查你擅长的本事的涉及深度。其实博主感到对于这些主题材料,能够整合你项目中用到的某二个能力以来就好了。

参谋答案:

 轻巧谈谈MEF在我们项目里面包车型大巴使用呢。

在谈MEF此前,我们不能够不要先谈谈DIP、IOC、DI

借助倒置原则(DIP):一种软件框架结构划设想计的规范化(抽象概念)

支配反转(IoC):一种反转流、正视和接口的艺术(DIP的切实落到实处际景况势)。

借助于注入(DI):IoC的一种达成形式,用来反转依赖(IoC的切切实实贯彻情势)。

哪些意思啊?约等于说,大家在软件架构的长河中,层和层之间通过接口依赖,下层不是直接给上层提供完毕,而是提供接口,具体的兑现以注重注入的办法在运维的时候动态注入进来。MEF就是落到实处依据注入的一种组件。它的施用使得UI层不直接重视于BLL层,而是借助于中间的一个IBLL层,在程序运维的时候,通过MEF动态将BLL里面包车型地铁贯彻注入到UI层里面去,那样做的补益是压缩了层与层之间的耦合。那也多亏面向接口编制程序格局的反映。

十四、自身写过JS组件吗?譬喻表达。

并发指数:三颗星

根本考场:此题考的js组件封装和js闭包的有的用法。一般的话,还是笔试出现的可能率一点都不小。

参考答案:自定义html的select组件

 

图片 5

//combobox
(function ($) {
    $.fn.combobox = function (options, param) {
        if (typeof options == 'string') {
            return $.fn.combobox.methods[options](this, param);
        }
        options = $.extend({}, $.fn.combobox.defaults, options || {});
        var target = $(this);
        target.attr('valuefield', options.valueField);
        target.attr('textfield', options.textField);
        target.empty();
        var option = $('

');
        option.attr('value', '');
        option.text(options.placeholder);
        target.append(option);
        if (options.data) {
            init(target, options.data);
        }
        else {
            //var param = {};
            options.onBeforeLoad.call(target, option.param);
            if (!options.url) return;
            $.getJSON(options.url, option.param, function (data) {
                init(target, data);
            });
        }
        function init(target, data) {
            $.each(data, function (i, item) {
                var option = $('

');
                option.attr('value', item[options.valueField]);
                option.text(item[options.textField]);
                target.append(option);
            });
            options.onLoadSuccess.call(target);
        }
        target.unbind("change");
        target.on("change", function (e) {
            if (options.onChange)
                return options.onChange(target.val());
        });
    }
    $.fn.combobox.methods = {
        getValue: function (jq) {
            return jq.val();
        },
        setValue: function (jq, param) {
            jq.val(param);
        },
        load: function (jq, url) {
            $.getJSON(url, function (data) {
                jq.empty();
                var option = $('

');
                option.attr('value', '');
                option.text('请选择');
                jq.append(option);
                $.each(data, function (i, item) {
                    var option = $('

');
                    option.attr('value', item[jq.attr('valuefield')]);
                    option.text(item[jq.attr('textfield')]);
                    jq.append(option);
                });
            });
        }
    };
    $.fn.combobox.defaults = {
        url: null,
        param: null,
        data: null,
        valueField: 'value',
        textField: 'text',
        placeholder: '请选择',
        onBeforeLoad: function (param) { },
        onLoadSuccess: function () { },
        onChange: function (value) { }
    };
})(jQuery);

图片 6

调用的时候

        $("#sel_search_orderstatus").combobox({
            url: '/apiaction/Order/OrderApi/GetOrderStatu',
            valueField: 'VALUE',
            textField: 'NAME'
        });

就会半自动从后台取多少,注意valueField和textField对应要显得和实际值。

十五、自个儿写过二十十二线程组件吗?简要表达!

并发指数:三颗星

最首要考试的地点:此题是两年前博主在携程的叁遍电话面试中遇到的,别的地点多数没境遇过,其实到昨日也不能够清楚当下边试官问那一个标题标指标。但本身想,此主题素材必有出处,推断面试官是想打听您对多线程以及线程池等的敞亮深度。

仿效答案:能够参照

 

 

 

相关文章