Angular 從入坑到挖坑 – 路由守衛連連看_貨運

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

一、Overview

Angular 入坑記錄的筆記第六篇,介紹 Angular 路由模塊中關於路由守衛的相關知識點,了解常用到的路由守衛接口,知道如何通過實現路由守衛接口來實現特定的功能需求,以及實現對於特性模塊的惰性加載

對應官方文檔地址:

  • 路由與導航

配套代碼地址:angular-practice/src/router-combat

二、Contents

  1. Angular 從入坑到棄坑 – Angular 使用入門
  2. Angular 從入坑到挖坑 – 組件食用指南
  3. Angular 從入坑到挖坑 – 表單控件概覽
  4. Angular 從入坑到挖坑 – HTTP 請求概覽
  5. Angular 從入坑到挖坑 – Router 路由使用入門指北
  6. Angular 從入坑到挖坑 – 路由守衛連連看

三、Knowledge Graph

四、Step by Step

4.1、基礎準備

重複上一篇筆記的內容,搭建一個包含路由配置的 Angualr 項目

新建四個組件,分別對應於三個實際使用到的頁面與一個設置為通配路由的 404 頁面

-- 危機中心頁面
ng g component crisis-list

-- 英雄中心頁面
ng g component hero-list

-- 英雄相親頁面
ng g component hero-detail

-- 404 頁面
ng g component page-not-found 

在 app-routing.module.ts 文件中完成對於項目路由的定義,這裏包含了對於路由的重定向、通配路由,以及通過動態路由進行參數傳遞的使用

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

// 引入組件
import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { HeroListComponent } from './hero-list/hero-list.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

const routes: Routes = [
  {
    path: 'crisis-center',
    component: CrisisListComponent,
  },
  {
    path: 'heroes',
    component: HeroListComponent,
  },
  {
    path: 'hero/:id',
    component: HeroDetailComponent,
  },
  {
    path: '',
    redirectTo: '/heroes',
    pathMatch: 'full',
  },
  {
    path: '**',
    component: PageNotFoundComponent,
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule { }

之後,在根組件中,添加 router-outlet 標籤用來聲明路由在頁面上渲染的出口

<h1>Angular Router</h1>
<nav>
  <a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a> &nbsp;&nbsp;
  <a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>

4.2、路由守衛

在 Angular 中,路由守衛主要可以解決以下的問題

  • 對於用戶訪問頁面的權限校驗(是否已經登錄?已經登錄的角色是否有權限進入?)
  • 在跳轉到組件前獲取某些必須的數據
  • 離開頁面時,提示用戶是否保存未提交的修改

Angular 路由模塊提供了如下的幾個接口用來幫助我們解決上面的問題

  • CanActivate:用來處理系統跳轉到到某個路由地址的操作(判斷是否可以進行訪問)
  • CanActivateChild:功能同 CanActivate,只不過針對的是子路由
  • CanDeactivate:用來處理從當前路由離開的情況(判斷是否存在未提交的信息)
  • CanLoad:是否允許通過延遲加載的方式加載某個模塊

在添加了路由守衛之後,通過路由守衛返回的值,從而達到我們控制路由的目的

  • true:導航將會繼續
  • false:導航將會中斷,用戶停留在當前的頁面或者是跳轉到指定的頁面
  • UrlTree:取消當前的導航,並導航到路由守衛返回的這個 UrlTree 上(一個新的路由信息)
4.2.1、CanActivate:認證授權

在實現路由守衛之前,可以通過 Angular CLI 來生成路由守衛的接口實現類,通過命令行,在 app/auth 路徑下生成一個授權守衛類,CLI 會提示我們選擇繼承的路由守衛接口,這裏選擇 CanActivate 即可

ng g guard auth/auth

在 AuthGuard 這個路由守衛類中,我們模擬了是否允許訪問一個路由地址的認證授權。首先判斷是否已經登錄,如果登錄后再判斷當前登錄人是否具有當前路由地址的訪問權限

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  /**
   * ctor
   * @param router 路由
   */
  constructor(private router: Router) { }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

    // 判斷是否有 token 信息
    let token = localStorage.getItem('auth-token') || '';
    if (token === '') {
      this.router.navigate(['/login']);
      return false;
    }

    // 判斷是否可以訪問當前連接
    let url: string = state.url;
    if (token === 'admin' && url === '/crisis-center') {
      return true;
    }

    this.router.navigate(['/login']);
    return false;
  }
}

之後我們就可以在 app-routing.module.ts 文件中引入 AuthGuard 類,針對需要保護的路由進行路由守衛的配置

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

// 引入組件
import { CrisisListComponent } from './crisis-list/crisis-list.component';

// 引入路由守衛
import { AuthGuard } from './auth/auth.guard';

const routes: Routes = [
  {
    path: 'crisis-center',
    component: CrisisListComponent,
    canActivate: [AuthGuard], // 添加針對當前路由的 canActivate 路由守衛
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule { }

4.2.2、CanActivateChild:針對子路由的認證授權

與繼承 CanActivate 接口進行路由守衛的方式相似,針對子路由的認證授權可以通過繼承 CanActivateChild 接口來實現,因為授權的邏輯很相似,這裏通過多重繼承的方式,擴展 AuthGuard 的功能,從而達到同時針對路由和子路由的路由守衛

改造下原先 canActivate 方法的實現,將認證邏輯修改為用戶的 token 信息中包含 admin 即可訪問 crisis-center 頁面,在針對子路由進行認證授權的 canActivateChild 方法中,通過判斷 token 信息是否為 admin-master 模擬完成對於子路由的訪問認證

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router, CanActivateChild } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate, CanActivateChild {

  /**
   * ctor
   * @param router 路由
   */
  constructor(private router: Router) { }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

    // 判斷是否有 token 信息
    let token = localStorage.getItem('auth-token') || '';
    if (token === '') {
      this.router.navigate(['/login']);
      return false;
    }

    // 判斷是否可以訪問當前連接
    let url: string = state.url;
    if (token.indexOf('admin') !== -1 && url.indexOf('/crisis-center') !== -1) {
      return true;
    }

    this.router.navigate(['/login']);
    return false;
  }

  canActivateChild(
    childRoute: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
    let token = localStorage.getItem('auth-token') || '';
    if (token === '') {
      this.router.navigate(['/login']);
      return false;
    }

    return token === 'admin-master';
  }
}

通過 Angular CLI 新增一個 crisis-detail 組件,作為 crisis-list 的子組件

ng g component crisis-detail

接下來在 crisis-list 中添加 router-outlet 標籤,用來定義子路由的渲染出口

<h2>危機中心</h2>

<ul class="crises">
  <li *ngFor="let crisis of crisisList">
    <a [routerLink]="[crisis.id]">
      <span class="badge">{{ crisis.id }}</span>{{ crisis.name }}
    </a>
  </li>
</ul>

<!-- 定義子路由的渲染出口 -->
<router-outlet></router-outlet>

在針對子路由的認證授權配置時,我們可以選擇針對每個子路由添加 canActivateChild 屬性,也可以定義一個空地址的子路由,將所有歸屬於 crisis-list 的子路由作為這個空路由的子路由,通過針對這個空路徑添加 canActivateChild 屬性,從而實現將守護規則應用到所有的子路由上

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

這裏其實相當於將原先兩級的路由模式(父:crisis-list,子:crisis-detail)改成了三級(父:crisis-list,子:’ ‘(空路徑),孫:crisis-detail)

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

// 引入組件
import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';

// 引入路由守衛
import { AuthGuard } from './auth/auth.guard';

const routes: Routes = [
  {
    path: 'crisis-center',
    component: CrisisListComponent,
    canActivate: [AuthGuard], // 添加針對當前路由的 canActivate 路由守衛
    children: [{
      path: '',
      canActivateChild: [AuthGuard], // 添加針對子路由的 canActivate 路由守衛
      children: [{
        path: 'detail',
        component: CrisisDetailComponent
      }]
    }]
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule { }

4.2.3、CanDeactivate:處理用戶未提交的修改

當進行表單填報之類的操作時,因為會涉及到一個提交的動作,當用戶沒有點擊保存按鈕就離開時,最好能暫停,對用戶進行一個友好性的提示,由用戶選擇後續的操作

創建一個路由守衛,繼承於 CanDeactivate 接口

ng g guard hero-list/guards/hero-can-deactivate

與上面的 CanActivate、CanActivateChild 路由守衛的使用方式不同,對於 CanDeactivate 守衛來說,我們需要將參數中的 unknown 替換成我們實際需要進行路由守衛的組件

import { Injectable } from '@angular/core';
import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class HeroCanDeactivateGuard implements CanDeactivate<unknown> {
  canDeactivate(
    component: unknown,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot,
    nextState?: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return true;
  }
  
}

例如,這裏針對的是 HeroListComponent 這個組件,因此我們需要將泛型的參數 unknown 改為 HeroListComponent,通過 component 參數,就可以獲得需要進行路由守衛的組件的相關信息

import { Injectable } from '@angular/core';
import {
  CanDeactivate,
  ActivatedRouteSnapshot,
  RouterStateSnapshot,
  UrlTree,
} from '@angular/router';
import { Observable } from 'rxjs';

// 引入需要進行路由守衛的組件
import { HeroListComponent } from '../hero-list.component';

@Injectable({
  providedIn: 'root',
})
export class HeroCanDeactivateGuard
  implements CanDeactivate<HeroListComponent> {
  canDeactivate(
    component: HeroListComponent,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot,
    nextState?: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {

    // 判斷是否修改了原始數據
    //
    const data = component.hero;
    if (data === undefined) {
      return true;
    }
    const origin = component.heroList.find(hero => hero.id === data.id);
    if (data.name === origin.name) {
      return true;
    }

    return window.confirm('內容未提交,確認離開?');
  }
}

這裏模擬判斷用戶有沒有修改原始的數據,當用戶修改了數據並移動到別的頁面時,觸發路由守衛,提示用戶是否保存后再離開當前頁面

4.3、異步路由

4.3.1、惰性加載

當應用逐漸擴大,使用現有的加載方式會造成應用在第一次訪問時就加載了全部的組件,從而導致系統首次渲染過慢。因此這裏可以使用惰性加載的方式在請求具體的模塊時才加載對應的組件

惰性加載只針對於特性模塊(NgModule),因此為了使用惰性加載這個功能點,我們需要將系統按照功能劃分,拆分出一個個獨立的模塊

首先通過 Angular CLI 創建一個危機中心模塊(crisis 模塊)

-- 查看創建模塊的相關參數
ng g module --help

-- 創建危機中心模塊(自動在 app.moudule.ts 中引入新創建的 CrisisModule、添加當前模塊的路由配置)
ng g module crisis --module app --routing

將 crisis-list、crisis-detail 組件全部移動到 crisis 模塊下面,並在 CrisisModule 中添加對於 crisis-list、crisis-detail 組件的聲明,同時將原來在 app.module.ts 中聲明的組件代碼移除

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { CrisisRoutingModule } from './crisis-routing.module';

import { FormsModule } from '@angular/forms';

// 引入模塊中使用到的組件
import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';


@NgModule({
  declarations: [
    CrisisListComponent,
    CrisisDetailComponent
  ],
  imports: [
    CommonModule,
    FormsModule,
    CrisisRoutingModule
  ]
})
export class CrisisModule { }

同樣的,將當前模塊的路由配置移動到專門的路由配置文件 crisis-routing.module.ts 中,並將 app-routing.module.ts 中相關的路由配置刪除

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

// 引入組件
import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';

// 引入路由守衛
import { AuthGuard } from '../auth/auth.guard';

const routes: Routes = [{
  path: '',
  component: CrisisListComponent,
  canActivate: [AuthGuard], // 添加針對當前路由的 canActivate 路由守衛
  children: [{
    path: '',
    canActivateChild: [AuthGuard], // 添加針對子路由的 canActivate 路由守衛
    children: [{
      path: 'detail',
      component: CrisisDetailComponent
    }]
  }]
}];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class CrisisRoutingModule { }

重新運行項目,如果你在創建模塊的命令中設置了自動引入當前模塊到 app.module.ts 文件中,大概率會遇到下面的問題

這裏的問題與配置通配路由需要放到最後的原因相似,因為腳手架在幫我們將創建的模塊導入到 app.module.ts 中時,是添加到整個數組的最後,同時因為我們已經將 crisis 模塊的路由配置移動到專門的 crisis-routing.module.ts 中了,框架在進行路由匹配時會預先匹配上 app-routing.module.ts 中設置的通配路由,從而導致無法找到實際應該對應的組件,因此這裏我們需要將 AppRoutingModule 放到聲明的最後

當問題解決后,就可以針對 crisis 模塊設置惰性加載

在配置惰性路由時,我們需要以一種類似於子路由的方式進行配置,通過路由的 loadChildren 屬性來加載對應的模塊,而不是具體的組件,修改后的 AppRoutingModule 代碼如下

import { HeroCanDeactivateGuard } from './hero-list/guards/hero-can-deactivate.guard';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: 'crisis-center',
    loadChildren: () => import('./crisis/crisis.module').then(m => m.CrisisModule)
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes, { enableTracing: true })],
  exports: [RouterModule],
})
export class AppRoutingModule { }

當導航到這個 /crisis-center 路由時,框架會通過 loadChildren 字符串來動態加載 CrisisModule,然後把 CrisisModule 添加到當前的路由配置中,而惰性加載和重新配置工作只會發生一次,也就是在該路由首次被請求時執行,在後續請求時,該模塊和路由都是立即可用的

4.3.2、CanLoad:杜絕未通過認證授權的組件加載

在上面的代碼中,對於 CrisisModule 模塊我們已經使用 CanActivate、CanActivateChild 路由守衛來進行路由的認證授權,但是當我們並沒有權限訪問該路由的權限,卻依然點擊了鏈接時,此時框架路由仍會加載該模塊。為了杜絕這種授權未通過仍加載模塊的問題發生,這裏需要使用到 CanLoad 守衛

因為這裏的判斷邏輯與認證授權的邏輯相同,因此在 AuthGuard 中,繼承 CanLoad 接口即可,修改后的 AuthGuard 代碼如下

import { Injectable } from '@angular/core';
import {
  CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router, CanActivateChild, CanLoad, Route, UrlSegment
} from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {

  /**
   * ctor
   * @param router 路由
   */
  constructor(private router: Router) { }


  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

    // 判斷是否有 token 信息
    let token = localStorage.getItem('auth-token') || '';
    if (token === '') {
      this.router.navigate(['/login']);
      return false;
    }

    // 判斷是否可以訪問當前連接
    let url: string = state.url;
    if (token.indexOf('admin') !== -1 && url.indexOf('/crisis-center') !== -1) {
      return true;
    }

    this.router.navigate(['/login']);
    return false;
  }

  canActivateChild(
    childRoute: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
    let token = localStorage.getItem('auth-token') || '';
    if (token === '') {
      this.router.navigate(['/login']);
      return false;
    }

    return token === 'admin-master';
  }

  canLoad(route: Route, segments: UrlSegment[]): boolean | Observable<boolean> | Promise<boolean> {
    let token = localStorage.getItem('auth-token') || '';
    if (token === '') {
      this.router.navigate(['/login']);
      return false;
    }

    let url = `/${route.path}`;

    if (token.indexOf('admin') !== -1 && url.indexOf('/crisis-center') !== -1) {
      return true;
    }
  }
}

同樣的,針對路由守衛的實現完成后,將需要使用到的路由守衛添加到 crisis-center 路由的 canLoad 數組中即可實現授權認證不通過時不加載模塊

import { HeroCanDeactivateGuard } from './hero-list/guards/hero-can-deactivate.guard';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: 'crisis-center',
    loadChildren: () => import('./crisis/crisis.module').then(m => m.CrisisModule)
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes, { enableTracing: true })],
  exports: [RouterModule],
})
export class AppRoutingModule { }

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

【大廠面試02期】Redis過期key是怎麼樣清理的?_貨運

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

【大廠面試02期】Redis過期key是怎麼樣清理的?

在Redis中,對於過期key的清理主要有惰性清除,定時清理,內存不夠時清理三種方法,下面我們就來具體看看這三種清理方法。

(1)惰性清除

在訪問key時,如果發現key已經過期,那麼會將key刪除。

(2)定時清理

Redis配置項hz定義了serverCron任務的執行周期,默認每次清理時間為25ms,每次清理會依次遍歷所有DB,從db隨機取出20個key,如果過期就刪除,如果其中有5個key過期,那麼就繼續對這個db進行清理,否則開始清理下一個db。

(3)內存不夠時清理

當執行寫入命令時,如果發現內存不夠,那麼就會按照配置的淘汰策略清理內存,淘汰策略一般有6種,Redis4.0版本后又增加了2種,主要由分為三類

  • 第一類 不處理,等報錯(默認的配置)

    • noeviction,發現內存不夠時,不刪除key,執行寫入命令時直接返回錯誤信息。(Redis默認的配置就是noeviction)
  • 第二類 從所有結果集中的key中挑選,進行淘汰

    • allkeys-random 就是從所有的key中隨機挑選key,進行淘汰
    • allkeys-lru 就是從所有的key中挑選最近使用時間距離現在最遠的key,進行淘汰
    • allkeys-lfu 就是從所有的key中挑選使用頻率最低的key,進行淘汰。(這是Redis 4.0版本后新增的策略)
  • 第三類 從設置了過期時間的key中挑選,進行淘汰

    這種就是從設置了expires過期時間的結果集中選出一部分key淘汰,挑選的算法有:

    ※智慧手機時代的來臨,RWD網頁設計為架站首選

    網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

    • volatile-random 從設置了過期時間的結果集中隨機挑選key刪除。

    • volatile-lru 從設置了過期時間的結果集中挑選上次使用時間距離現在最久的key開始刪除

    • volatile-ttl 從設置了過期時間的結果集中挑選可存活時間最短的key開始刪除(也就是從哪些快要過期的key中先刪除)

    • volatile-lfu 從過期時間的結果集中選擇使用頻率最低的key開始刪除(這是Redis 4.0版本后新增的策略)

LRU算法

LRU算法的設計原則是如果一個數據近期沒有被訪問到,那麼之後一段時間都不會被訪問到。所以當元素個數達到限制的值時,優先移除距離上次使用時間最久的元素。

可以使用雙向鏈表Node+HashMap<String, Node>來實現,每次訪問元素后,將元素移動到鏈表頭部,當元素滿了時,將鏈表尾部的元素移除,HashMap主要用於根據key獲得Node以及添加時判斷節點是否已存在和刪除時快速找到節點。

PS:使用單向鏈表能不能實現呢,也可以,單向鏈表的節點雖然獲取不到pre節點的信息,但是可以將下一個節點的key和value設置在當前節點上,然後把當前節點的next指針指向下下個節點,這樣相當於把下一個節點刪除了

//雙向鏈表
    public static class ListNode {
        String key;//這裏存儲key便於元素滿時,刪除尾節點時可以快速從HashMap刪除鍵值對
        Integer value;
        ListNode pre = null;
        ListNode next = null;
        ListNode(String key, Integer value) {
            this.key = key;
            this.value = value;
        }
    }

    ListNode head;
    ListNode last;
    int limit=4;
    
    HashMap<String, ListNode> hashMap = new HashMap<String, ListNode>();

    public void add(String key, Integer val) {
        ListNode existNode = hashMap.get(key);
        if (existNode!=null) {
            //從鏈表中刪除這個元素
            ListNode pre = existNode.pre;
            ListNode next = existNode.next;
            if (pre!=null) {
               pre.next = next;
            }
            if (next!=null) {
               next.pre = pre;
            }
            //更新尾節點
            if (last==existNode) {
                last = existNode.pre;
            }
            //移動到最前面
            head.pre = existNode;
            existNode.next = head;
            head = existNode;
            //更新值
            existNode.value = val;
        } else {
            //達到限制,先刪除尾節點
            if (hashMap.size() == limit) {
                ListNode deleteNode = last;
                hashMap.remove(deleteNode.key);
              //正是因為需要刪除,所以才需要每個ListNode保存key
                last = deleteNode.pre;
                deleteNode.pre = null;
                last.next = null;
            }
            ListNode node = new ListNode(key,val);
            hashMap.put(key,node);
            if (head==null) {
                head = node;
                last = node;
            } else {
                //插入頭結點
                node.next = head;
                head.pre = node;
                head = node;
            }
        }

    }

    public ListNode get(String key) {
        return hashMap.get(key);
    }

    public void remove(String key) {
        ListNode deleteNode = hashMap.get(key);
        ListNode preNode = deleteNode.pre;
        ListNode nextNode = deleteNode.next;
        if (preNode!=null) {
            preNode.next = nextNode;
        }
        if (nextNode!=null) {
            nextNode.pre = preNode;
        }
        if (head==deleteNode) {
            head = nextNode;
        }
        if (last == deleteNode) {
            last = preNode;
        }
        hashMap.remove(key);
    }

LFU算法

LFU算法的設計原則時,如果一個數據在最近一段時間被訪問的時次數越多,那麼之後被訪問的概率會越大,基本實現是每個數據都有一個引用計數,每次數據被訪問后,引用計數加1,需要淘汰數據時,淘汰引用計數最小的數據。在Redis的實現中,每次key被訪問后,引用計數是加一個介於0到1之間的數p,並且訪問越頻繁p值越大,而且在一定的時間間隔內,
如果key沒有被訪問,引用計數會減少。

最後

大家有什麼想法,歡迎進群一起討論(因為大群已經滿200人了,大家可以掃碼進這個小群,我拉大家進大群)!本文已收錄到1.1K Star數開源學習指南——《大廠面試指北》,如果想要了解更多大廠面試相關的內容,了解更多可以看
http://notfound9.github.io/interviewGuide/#/docs/BATInterview

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

再給福克斯車主一次機會,他會買全新科魯茲嗎?_貨運

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

開起來怎麼樣。運動個性潮流指向。會選擇福克斯的車主,相信對操控性也有非常高的要求。張濤會對全新科魯茲的操控感給出什麼樣的評價也是最為好奇的一點。“全新科魯茲開起來非常輕盈,轉向靈敏,底盤調教得偏運動,但沒有失去舒適性,擁有一個有質感的底盤。

在1個月前曾經招募過幾位不同性格和不同車型的車主朋友,約他們來一場性能3.0時代中級車的試駕活動,當時邀請的朋友中也正好有一位福克斯資深車主,並且算是汽車界的老手,而福克斯作為一代人心目中代表着性能2.0時代的家轎,有着不可撼動的地位。那麼我們找到它的資深車主來試駕到底是no zuo no die還是打臉福克斯?

這次參加試駕的福克斯車主剛好就是大家所熟悉的帥哥張濤,作為一枚資深的福克斯前車主,他試駕完全新科魯茲后,在視頻裏面也表達了他的感受,立刻帶大家解密,請觀看以下視頻:

新外觀能否撼動車主固有審美?

視頻里這位福克斯資深車主張濤給予了全新科魯茲外觀極大的肯定:“全新科魯茲這一代的硬朗造型,從上一代繼承了下來,在這個看臉的時代,全新科魯茲把上一代的造型發揮得更淋漓盡致。”

在外觀這點上,和張濤的想法是一樣的。作為雪佛蘭品牌中最具運動特質的3C家族之一的全新科魯茲,繼承兄輩科爾維特以及科邁羅的力量感,在凌厲的線條為整車帶來肌肉感的同時,也恰如其分地採用了一些曲線讓它看起來更時尚。這樣的全新科魯茲顯然更容易抓住年輕一代的消費者的心。

車主大讚空間寬!

說到內部空間,張濤表示:“全新科魯茲的空間算是比福克斯好一點,橫向空間感很強,不會讓人有局促的感覺。”

本人也坐在後排感受過,確實在A級車裡面,全新科魯茲的空間表現可說是非常優秀,2700mm的軸距為此而貢獻了不少,腿部空間伸展綽綽有餘,所以這是和張濤都大為讚賞的空間設定。

配置上打動人 車主都認可的配置

當談到配置時,張濤也給出了非常正面的評價:“全新科魯茲擁有一些實用的配置,如胎壓監測,全系車型標配的啟停功能,最高配置擁有連福克斯頂配都沒有的座椅加熱和電動調節功能。”

認為胎壓檢測這個功能標配是要為全新科魯茲點贊的,作為在國外標配的一個安全型的配置,胎壓監測已經逐步受到市場和消費者的重視,

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

畢竟安全駕駛的重要性已經逐漸被國人所接受和認同。而座椅加熱和電動調節,自動啟停等功能也都是為了駕駛者貼心設計的,尤其是自動啟停功能更是大大降低了油耗和用車成本。據權威機構測試,此項技術的使用將使一輛普通轎車每年節省10%至15%的燃料。這點只能說雪佛蘭為消費者想得的確非常周到。

開起來怎麼樣?運動個性潮流指向?

會選擇福克斯的車主,相信對操控性也有非常高的要求。張濤會對全新科魯茲的操控感給出什麼樣的評價也是最為好奇的一點。

“全新科魯茲開起來非常輕盈,轉向靈敏,底盤調教得偏運動,但沒有失去舒適性,擁有一個有質感的底盤。”

也開過這台車,要說全新科魯茲標志著性能車3.0時代的來臨,確實沒有誇張,高速段開到120公里車身仍然保持很穩的狀態,變道時方向盤的轉向很精準,與一些虛位較大的車型相比,簡直省心,而這真正給予了駕駛者更多的信心。若要給全新科魯茲打個分,可以給到93以上的高分,怕給滿分會驕傲,所以還是要留一些進步的空間。

總結:

大家看到最後,相信都了解張濤對這台全新科魯茲給出了非常不錯的評價,而也很看好全新科魯茲的市場表現,即使最近全新福克斯也上市了不久,但是在空間上仍然是全新科魯茲佔優,並且綜合工況油耗也是全新科魯茲更省,而且全系標配的胎壓監測裝置等對於一些車主選車來說,都將是決定性因素。

(私底下和張濤深入溝通過,對於他來說,開了汽車那麼多年,從他的角度看,本次全新科魯茲試駕確實給到了他一些駕駛上的新鮮感,對於雪佛蘭造車,也顛覆了他對家轎的一些舊有觀念,感受到了全新科魯茲的一些配置驚喜,是一次全新的駕駛體驗。)

在體驗為先的性能3.0時代里,能否給消費者帶來真正的全方位用戶體驗才是制勝關鍵。對比起上一代還停留在標榜數據的性能2.0時代的福克斯,全新科魯茲已經不單單隻是冰冷的駕駛机械。這一天下來的駕駛,讓這位資深福克斯車主全面接觸這台中級車,雪佛蘭全新科魯茲在這位資深福克斯車主的心目中相信已經留下了不少深刻的印象。回到我們的問題:再給福克斯車主一次機會,他會買全新科魯茲嗎?答案似乎已經不言而喻。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

一帶一路又惹議 中國在克什米爾建水電廠引大規模示威_貨運

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

摘錄自2020年7月7日中央社報導

國際亞洲新聞社(ANI)等印度媒體今(7日)報導,巴基斯坦控制克什米爾首府穆薩法拉巴德(Muzaffarabad)居民昨天舉行示威活動,譴責中國財團在尼肋姆河和吉魯姆河興建尼肋姆-吉魯姆(Neelum-Jhelum)水力發電廠和柯哈拉(Kohala)水力發電廠工程是非法建設,且嚴重破壞當地環境生態。

當地居民指控,水力發電廠營運後,會把尼肋姆河90%的河水轉移到發電廠,導致養活穆薩法拉巴德50萬人口的尼肋姆河流量和水位下降,影響當地居民生計,且引發當地氣溫升高。

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

尼肋姆-吉魯姆水力發電廠和柯哈特水力發電廠興建項目,都是中國「一帶一路」下「中巴經濟走廊」的項目。其中,尼肋姆-吉魯姆水力發電廠從2008年開始興建,2018年8月完成;柯哈特水力發電廠工程則於2015年由中國長江三峽集團得標,於2018年起也引發當地居民抗議迄今。

生物多樣性
生態保育
國際新聞
中國新聞
巴基斯坦
水力發電廠
一帶一路
集水區

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

SpringSecurity(1)—認證+授權代碼實現_貨運

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

認證+授權代碼實現

Spring Security是 一種基於 Spring AOP 和 Servlet 過濾器的安全框架。它提供全面的安全性解決方案,同時在 Web 請求級和方法調用級處理身份確認和授權。

有關認證和授權的理論知識,之前有寫過相關博客。了解權限管理

一、SpringSceurity工作流程

網上找一張圖,覺得畫的挺好的,比較容易理解。不然換的是源碼流程圖很難去理解。

圖片地址 : 地址 可以單機放大看更加清楚

要想理解這張圖建議看下這篇博客,因為這張圖中需要自定義的My…類,在文章中都有說明,所以更好理解點。

Spring Boot Security 詳解

二、認證+授權代碼

這裏只展示一些核心代碼,具體完整代碼放在github上。

1、UserDetails接口

Security 中的用戶接口,我們自定義用戶類要實現該接口, 用於向security中注入當前用戶的姓名密碼,和擁有的角色。同時也包含一些其它信息,比如當前用戶是否過期,

賬號是否鎖定等等。

自己定義User實現這個接口

public class User implements UserDetails {
    private String username;
    private String password;
    private List<Role> roles;
    /**
     * 獲取用戶名
     */
    @Override
    public String getUsername() {
        return username;
    }
    /**
     * 獲取密碼
     */
    @Override
    public String getPassword() {
        return password;
    }
    /**
     * 用戶的權限集, 默認需要添加ROLE_ 前綴
     */
    @Override
    @JsonIgnore
    public List<GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (Role role : roles) {
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getName()));
        }
        return authorities;
    }
    /**
     * 賬戶是否過期
     */
    @Override
    @JsonIgnore
    public boolean isAccountNonExpired() {
        return true;
    }
    /**
     * 賬戶是否鎖定
     */
    @Override
    @JsonIgnore
    public boolean isAccountNonLocked() {
        return true;
    }
    /**
     * 憑證是否過期
     */
    @Override
    @JsonIgnore
    public boolean isCredentialsNonExpired() {
        return true;
    }
    /**
     * 用戶是否可用
     */
    @Override
    public boolean isEnabled() {
        return true;
    }  
}

2、UserDetailsService

Security 中的用戶 Service,自定義用戶服務類需要實現該接口。這個接口只有一個方法需要我們去實現,那就是通過用戶名去獲取用戶信息。這裏也是和數據庫交互獲取

用戶認證和授權信息的地方。

@Service
@Slf4j
public class UserService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        //TODO 正常應該查詢數據庫獲取用戶和用戶的權限
//        User user = userMapper.loadUserByUsername(userName);
//        List<Role> roles = rolesMapper.getRolesByUid(user.getId());
//        user.setRoles(roles);
        log.info("登陸用戶名: {}", userName);
        //通過用戶名查詢到的密碼 密碼肯定是加密過的 這裏明文密碼是 123456
        String password = "e10adc3949ba59abbe56e057f20f883e";
        //用戶對應權限
        List<Role> roles = Lists.newArrayList(new Role(1L, "教師"), new Role(2L, "學生"));
        User user = new User(userName, password, roles);
        return user;
    }
}

注意 這裏的明文密碼是 123456,也就是用戶輸入這個才能完成認證。授權的話當前用戶有兩個角色 教師學生。在下面測試的時候會用到。

3、WebSecurityConfigurerAdapter

它是Spring Security的Java 配置類。創建類SecurityConfiguration繼承 WebSecurityConfigurerAdapter,來對我們應用中所有的安全相關的事項(

所有url,驗證用戶名密碼,表單重定向等)進行控制。

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 1、配置的是認證信息, AuthenticationManagerBuilder 這個類,就是AuthenticationManager的建造者, 我們只需要向這個類中, 配置用戶信息,
     *    就能生成對應的AuthenticationManager, 這個類也提過,是用戶身份的管理者, 是認證的入口, 因此,我們需要通過這個配置,想security提供真實的用戶身份。
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    }
    /**
     * 2、配置Security的認證策略, 每個模塊配置使用and結尾。這個也是最複雜的
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    }
    /**
     * 3、這個配置方法用於配置靜態資源的處理方式,可使用 Ant 匹配規則。就是可以不用認證就可以直接訪問的接口
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
    }
}

完整示例

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;
    /**
     * 密碼驗證器
     */
    @Autowired
    private PassWordEncorder passWordEncorder;
    /**
     * 成功處理器
     */
    @Autowired
    private AuthenctiationSuccessHandler authenctiationSuccessHandler;

    /**
     * 失敗處理器
     */
   @Autowired
   private AuthenctiationFailHandler authenctiationFailHandler;
   /**
    * 向Security注入用戶信息
    */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passWordEncorder);
    }
    /**
     * 配置規則
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //開啟登陸配置
        http.authorizeRequests()
                // 登錄之後就能訪問
                .antMatchers("/no-authorize").authenticated()
                // 登陸后 需要校長角色權限
                .antMatchers("/need-authorize").hasRole("校長")
                // 其他的路徑都是登錄后即可訪問
                .anyRequest().authenticated()
                .and().formLogin()
                // 定義登錄頁面,未登錄時,訪問一個需要登錄之後才能訪問的接口,會自動跳轉到該頁面
                .loginPage("/login_page")
                //登錄成功的處理器
                .successHandler(authenctiationSuccessHandler)
                //登錄失敗的處理器
                .failureHandler(authenctiationFailHandler)
                // 登錄處理接口
                .loginProcessingUrl("/login")
                // 定義登錄時,用戶名的 key,默認為 username
                .usernameParameter("username")
                //定義登錄時,用戶密碼的 key,默認為 password
                .passwordParameter("password").permitAll()
                .and().logout()
                ////和表單登錄相關的接口統統都直接通過
                .permitAll()
                .and().csrf().disable().exceptionHandling().accessDeniedHandler(getAccessDeniedHandler());
    }

    /**
     * 對於/static/  下的路徑都不用認證
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/no-login");
    }

    /**
     * 用戶未認證異常攔截
     */
    @Bean
    AccessDeniedHandler getAccessDeniedHandler() {
        return new AuthenticationAccessDeniedHandler();
    }
}

注意 這裏一共配置了三個路徑用於測試。

1、/no-login 接口不需要認證就可以直接訪問
2、/no-authorize 需要認證 但不需要授權就可以訪問
3、/need-authorize 首先需要認證 認證通過還需要授權 這裏需要校長的角色才可以訪問該接口 但是我們測試用戶只有教師和學生所以沒有權限訪問該接口

下面會針對這個個接口分別進行測試。

三、測試

1、接口提供

@RestController
public class TestController {

    /**
     * 1、不需要登陸就可以訪問
     */
    @RequestMapping(value = "/no-login")
    public ServiceResponse noLogin() {
        return ServiceResponse.success("歡迎訪問不需要登陸接口");
    }
    /**
     * 2、只登陸,不許認證接口
     */
    @RequestMapping(value = "/no-authorize")
    public ServiceResponse needAuthorize(){
        return ServiceResponse.success("登陸了 不用授權");
    }
    /**
     * 3、登陸 + 相關認證接口
     */
    @RequestMapping(value = "/need-authorize")
    public ServiceResponse noAuthorize() {
        return ServiceResponse.success("登陸+授權成功");
    }
    /**
     * @Description: 如果自動跳轉到這個頁面,說明用戶未登錄,返回相應的提示即可
     */
    @RequestMapping("/login_page")
    public ServiceResponse loginPage() {
        return  ServiceResponse.failure("001", "尚未登錄,請登錄!");
    }
}

2、未登錄訪問 no-login 和 no-authorize 接口

no-login接口

很明顯沒有登陸 請求該接口成功!

no-authorize接口

沒有登陸訪問失敗,在上面配置了如果用戶沒有認證的話跳轉到login_page接口,所以這裏返回 ‘尚未登錄,請登錄!’

3、登陸后訪問 no-authorize 和 need-authorize 接口

先登陸

根據上面配置登陸的路徑為 /login 請求參數包括 usernamepassword

注意 這裏需要post請求。

no-authorize 接口

登陸就可以訪問了。

need-authorize 接口

雖然登陸成功了,但是因為該接口需要校長角色,之前給該用戶只配置了教師和學生的角色所以訪問失敗。

參考

1、SpringSide 3 中的安全框架

2、Spring Security 工作原理概覽

3、Spring Boot Security 詳解 很贊

別人罵我胖,我會生氣,因為我心裏承認了我胖。別人說我矮,我就會覺得好笑,因為我心裏知道我不可能矮。這就是我們為什麼會對別人的攻擊生氣。
攻我盾者,乃我內心之矛(17)

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

10萬就可以輕鬆入手中型SUV 竟然還帶7座_貨運

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

採用全黑的內飾配色,大尺寸的中控屏非常醒目,整車質感良好,电子駐車、無鑰匙進入/啟動、車身穩定系統、倒車影像等配置比較齊全。儲物空間方面非常豐富,如中控台下方掏空的設計就非常方便放些零碎的東西,2780mm的軸距,帶來的是非常寬敞的空間感受,頭部、腿部空間都有很多餘量。

眾泰汽車-眾泰T600

指導價:7.98-14.98萬

外觀設計方面,眾泰T600給人很大氣的感覺,與途銳有着極其相似的前臉使它看起來一點都不陌生,尾部的造型圓潤不失動感,雙出的排氣管動感十足;內飾整體布局簡潔大方,仿木飾板和銀色飾條的搭配看起來很得體,6安全氣囊、胎壓監測、無鑰匙進入/啟動、自動駐車、倒車影像、自動頭燈等配置應有盡有;2807mm的軸距在同級別中佔有優勢,乘坐舒適度良好,儲物空間表現中規中矩,滿足日常使用;動力提供了1.5T(最大功率162馬力)/2.0T(最大功率190馬力)兩種車型選擇,搭配5擋手動或着6擋雙離合變速箱,動力響應足夠快,底盤的調校偏向舒適。

東風小康-東風風光580

指導價:7.29-9.99萬

風光580可謂是一款網紅級別的車型,外形設計較為動感,車身線條流暢優雅,三條鍍鉻格柵搭配大尺寸的六邊形進氣格柵,力量感十足,雙色多幅鋁合金輪轂與其時尚的外觀很般配;採用全黑的內飾配色,大尺寸的中控屏非常醒目,整車質感良好,

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

电子駐車、無鑰匙進入/啟動、車身穩定系統、倒車影像等配置比較齊全;儲物空間方面非常豐富,如中控台下方掏空的設計就非常方便放些零碎的東西,2780mm的軸距,帶來的是非常寬敞的空間感受,頭部、腿部空間都有很多餘量;1.5T發動機最大功率150馬力,搭配6擋手動或者CVT變速器,動力儲備較為充足,由於車身重心較高的原因,過一些較大顛簸路面時,晃動感會比較大。

長安汽車-長安CX70

指導價:6.89-8.49萬

長安CX70的外觀原創度還是蠻高的,車身看起來很粗獷、硬朗,但車身側面難免會給人一種麵包車的感覺,接近角23.5度,離去角25度,最小離地間隙達到190mm,通過性表現出色;內飾布局規整協調,橙黑雙色的搭配看起來很有活力,中控屏與空調控制系統集成在一起,取消了物理按鍵,非常有特斯拉大屏的那種檔次感,右側全景影像系統便利性很強;CX70的車身高度達到了1750mm,所以頭部空間非常寬敞,採用2+3+2的座椅布局,第三排座椅支持翻折,擴展性強;全系採用1.6L(最大功率117馬力)+5擋手動變速箱的動力組合,滿足日常城市道路使用,而且懸架支撐性好,期待渦輪增壓車型和自動擋的出現。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

市北區第二屆“時尚+體育”_貨運

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

市北區第二屆“時尚+體育”

       10月17日晚,市北區第二屆全民健身周開幕式在郵輪母港廣場盛大啟幕。本屆全民健身周由市北區教育和體育局主辦,以“啟航市北,時尚健身季”為主線,旨在引導廣大市民把健身活動作為新時尚,在運動中增強體質、傳播快樂、成就夢想、健康生活。

  市北區大力推進全民健身事業,創新發展體育服務產業,高配套迭代健身設施,舉辦多項最具動感、最適合各年齡段群眾的健身活動活動,讓“時尚+體育、科技+健身、互聯網+運動”多種業態覆蓋轄區,為建設國際航運貿易金融創新中心核心區增添新活力。

  時尚體育盛會,開啟時尚體育新發展

  開幕式展播了市北區全民健身活動的快閃視頻,內容涵蓋涵蓋學校體育、全民健身活動、體育場館,彰顯市北的運動活力。

  各類異彩紛呈的群體體育活動也在開幕式上演。活力四射的摩登街舞,充滿青春動感的啦啦操、拳擊操、青春健身操,力量十足的鴛鴦門武術套路、跆拳道表演,為島城市民帶來一場運動魅力的饕餮盛宴。

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

  本屆全民健身周活動中還將組織全民健身項目展示和群眾互動活動,舉辦太極功夫扇比賽、“勝道-市北杯”乒乓球聯賽等豐富多彩的賽事。

  運動釋放生命活力,助力美好夜經濟運動生活

  開幕式結束后,“時尚夜光秀”熒光跑活動接着在郵輪母港舉行。在2公里左右的路程中共設置了6個點標,500餘名參賽选手要在1個小時的時間內完成相應任務。

  在“照亮七十載”任務點標,參賽隊伍成員需要齊心協力共同點亮70周年裝置;在“發現新時代”任務點標,1名成員需要在互動屏前做出動作,其他成員在互動屏上找出指定關鍵詞;在“逐夢綠茵場”任務點標,參賽隊伍中成員輪流在指定位置踢球射門;在“我是追夢人”任務點標,參賽隊伍需要在霓虹燈拍照牆前喊出口號,拍攝集體照片;在“分類新時尚”任務點標,參賽隊伍需要在指定時間內將垃圾圖卡投入指定垃圾桶中;在“中國最動聽”任務點標,參賽者需要使用擺在地上的琴譜,用腳彈奏出“我和我的祖國”第一句。每個點標任務完成后,參賽者將會獲得一枚大會專用章,在時限內完成所有任務抵達終點的选手將每人獲得一枚獎牌和抽獎券,有機會獲得豐厚的獎品。

  在熒光跑活動途中,主辦方還將設置自我彩繪、塗鴉、熒光網紅牆打卡、主題燈光秀等群眾互動活動,在增加活動趣味性的同時,彰顯市民個性與活力。

  2019“時尚+體育”全民健身周將為市北的市民乃至島城市民帶來一場生動有趣、形式多樣的體育運動大餐,進一步推動全民健身戰略的發展,助力國際航運貿易金融創新中心核心區建設。

網站內容來源http://www.online.jx.cn/

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

這些高配置的七座SUV,不足10萬就可以落地!_貨運

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

內飾整體還是保持長安的的風格,對稱式的布局,使用起來比較方便。CX70的車身尺寸為:4680*1800*1750mm,軸距:2780mm,並且車身設計較長,這讓CX70車內的縱向空間有了一定的布局基礎,所以,CX70的第三排乘坐空間還算可以,正常身高(175左右)乘坐,比較不先的那麼局促,舒適性相比這個價位的七座車,較高一些。

其實生不生二胎對於買不買七座SUV來說並沒有太大的影響,就好像買漢蘭達一樣,多數人都是買的七座,但並不是每個用戶都是二胎家庭。而七座的最大好處就是,在人多的時候,可以載上七個人,雖然第三排的空間有些狹小,但至少可以把人給人運走,像五座車怎麼也就只能坐五個(別說後備箱坐人什麼的)。即使平日里不用第三排的座椅,也可以放倒,這樣後備箱的空間也大。所以差不多的價格,何不選七座車型呢。

當然,按照如今的消費水平,漢蘭達這種車並不是每個家庭都可以買得起,8-15萬之間是普遍家庭的預算資金範圍,而如今,在10萬內可以落地的七座車也有不少,例如下面這三款。

眾泰汽車-大邁X5

指導價:6.99-12.39萬

大邁X5雖然不能說和某一款車型極其相似,但是拆開各個部分來看,會找不少成熟車型的影子,不過,好看就行,管他呢。中控較為簡潔,規規整整,視覺上的效果還算有質感,但是觸感就暴露一切了。大邁X5是在五座的基礎上增加了第三排座椅,布局為2+3+2,相較之下比較緊湊,第三排的的乘坐空間不算太理想,成年人會感到辛苦。第三排座椅可以按照50/50比例放倒,放倒之後,和五座車型一樣。

眾泰一向以豐富配置為賣點之一,大邁X5也不例外,有1.5T和1.6L兩種動力選擇,1.5T車型選擇較多,整體的配置都比較平均,低配和次低配沒有配備牽引力控制和ESp,舒適性上的配置也較少,往上的車型都有配備,並且舒適性的上的配置也算豐富,頂配和次頂配車型多了電動天窗,全景天窗等的配置,車型之間的價格區間較少,都在2000-4000之間,所以選擇起來會比較理想化。如果日常使用的話,建議選擇中配車型即可滿足日常需求了。

長安汽車-長安CX70

指導價:6.89-8.49萬

CX70整體設計的比較硬朗,車身看上較長,不過這麼大車型,配個17寸的輪胎看起來確實有點不搭調。內飾整體還是保持長安的的風格,對稱式的布局,使用起來比較方便。CX70的車身尺寸為:4680*1800*1750mm,軸距:2780mm,並且車身設計較長,這讓CX70車內的縱向空間有了一定的布局基礎,所以,CX70的第三排乘坐空間還算可以,正常身高(175左右)乘坐,

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

比較不先的那麼局促,舒適性相比這個價位的七座車,較高一些。

CX70隻有1.6L一種動力可選,並且只有手動擋,低配和次低配沒有剎車輔助,牽引力控制,ESp,低配的舒適性上的配置少的可憐,但次低配車型以上就比較齊全一些,日常代步上也足夠。而中配的兩個車型,有些奇怪,價格低的有配備剎車輔助,牽引力控制,ESp,反而價格高的沒有配備,但是多了電動天窗,日間行車燈,其他都基本一致。而頂配車型則是多了定速巡航, 主駕駛位座椅電動調節,后視鏡加熱等一些配置。建議選擇中配車型較低價格的運動型版本,7.59萬元七個座位,加上不錯的配置,性價比較高。

力帆汽車-邁威

指導價:5.78-7.68萬

邁威整體的造型比較渾厚,帶了點一些硬派的風格,畢竟車身比較大,也不太設計走圓潤的路線。內飾視覺上的質感還算不錯,看起來上檔次,布局較為規整,對稱式布局,上手容易。邁威的車身尺寸為:4440*1760*1730mm,軸距:2720mm,七座布局為2+3+2,以尺寸而言,邁威在這個級別七座SUV中沒有什麼優勢,但車內空間還算比較充裕,頭部空間和腿部空間還算充裕,稱不上局促。第三排成年人乘坐會顯得較為局促,並且使用第三排之後,後備箱的空間變得很可憐。

邁威只有1.5L一種動力可選擇,配置上比較單薄,最低配車型的配置面板可以用可憐來形容,在往上的車型(除了頂配)雖然沒有配備剎車輔助,牽引力控制,車身穩定控制,但是可以選裝,算下來也比較划算,舒適性上的配置也夠日常使用,因為中配車型的裸車價比較低。而頂配車型有配備剎車輔助,牽引力控制,車身穩定控制,舒適性上的配置和中配車型相差不大。建議選擇中配車型,裸車價在6.68萬,算上選裝最多也就7萬多一些,相比之下,性價比還是不低的。

總結:雖然第三排座椅使用的幾率不大,但是有就好過沒有,畢竟有時候真的需要,而以上的三款車型,大邁X5雖然配置較高,但是在做工用料上有待提升,邁威價格雖然低,但是配置也較低,所以三款車型中比較推薦長安CX70,無論是在做工,價格,配置,空間,整體都比較均衡,要說不足的就是外觀的車身造型不太協調的樣子。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

波札那驚傳象群神秘死亡 已發現至少350頭大象屍體_貨運

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

摘錄自2020年7月2日自由時報報導

非洲國家波札那驚傳數百頭象群集體神秘死亡,自5月以來已發現至少350頭大象的屍體,目前已先排除是盜獵所致,並懷疑大象的神經系統疑似遭到攻擊,且尚未排除是否會傳染人類,有專家甚至擔心是否會引發公衛危機,據指已先送出樣本進行測試。

據《BBC》、《skyNews》等外媒報導指出,自5月初以來,死亡總數來到350頭,估計實際死亡數量更高,其中有7成的屍體都集中在水坑附近,死亡個體包含不同性別及年齡層,有些還活著的大象看起來也相當虛弱和瘦弱。

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

據英國慈善機構國家公園救援組織(National Park Rescue)的麥肯恩博士(McCann)表示,本次的象群死亡與乾旱無關,且早在5月波札那政府就初步排除是盜獵所致。雖然去年有至少100頭大象因炭疽桿菌(anthrax)死亡,但官方也初步排除此原因。他也提到,象群在瀕臨死亡前會詭異的繞著圈行走,且行走過程搖搖晃晃、跌跌撞撞,懷疑可能是神經系統遭到攻擊,因此目前還無法排除中毒或是染病的可能性。

物種保育
生物多樣性
國際新聞
波札那
非洲
大象
集體死亡

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

日本政府的太陽能紓困方針 幫助日企回流國內_貨運

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

文:宋瑞文(加州能源特約撰述)

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。