開着容易上癮,這3款10來萬的合資車,比朗逸好玩得多

6L的動力版本,會讓你在日常代步之餘,也能享受到小鋼炮的魅力。至於1。5T的,朋友,秋名山見。福克斯的短板在於儲物空間較為一般,後排在兩廂車這個級別裏面算是表現一般,中下的水平。致悅,沒錯,不是致炫,是來自菲亞特选手的致悅,至於為啥會推薦它,不是它表現的多突出,主要是價格便宜,優惠還大,這是許多人買車考慮的問題之一。

緊湊型車三廂的感覺操控不過來?

有便宜的兩廂車推薦嗎?

想買兩廂車怎麼辦?

有哪些兩廂車選擇?

首先是來自馬自達选手帶來的昂科賽拉,對於這款車大家都不陌生,操控就不說了,兩廂車操控還不好也不好意思推薦了,昂科賽拉的底盤懸挂是想要表揚的,一個字,穩,即使是高速過彎,你也不會覺得虛。

在眾多車企紛紛投入渦輪增壓發動機的大軍中去是,馬自達堅持做自吸發動機,這簡直是個異類,但是馬自達憑藉創馳藍天技術使得昂科賽拉在動力方面不遜色於搭載渦輪發動機的車型,而且還省油,這也是馬自達敢拿自吸發動機打着運動旗號的原因了。

後排較小,是昂科賽拉的短板,這也是許多馬自達車型的短板了,買馬自達的朋友們要注意哦~

另外是昂科賽拉在胎躁控制方面的還是不夠,這是許多車主反應的問題了。

福特选手帶來的則是福克斯,福克斯是大家心目中的理想車型之一了,美系車的隔音好,配置豐富的特點都具備,還有眾多的動力選擇。

1.0T的動力總成,對於日常上下班代步通勤的朋友們,會說,夠用!1.6L的動力版本,會讓你在日常代步之餘,也能享受到小鋼炮的魅力!至於1.5T的,朋友,秋名山見!

福克斯的短板在於儲物空間較為一般,後排在兩廂車這個級別裏面算是表現一般,中下的水平。

致悅,沒錯,不是致炫,是來自菲亞特选手的致悅,至於為啥會推薦它,不是它表現的多突出,主要是價格便宜,優惠還大,這是許多人買車考慮的問題之一。

除了價格之外,致悅的空間表現以及動力表現也是挺不錯的,全系搭載1.4T渦輪增壓發動機,動力能說不夠嗎?用車主的話說,就是一給油就跑!

從車身尺寸以及乘坐空間測試來看,致悅的表現在同級別不能說最好,但是中上水平還是可以有的。而讓人不滿意的是所搭配的DCT雙離合變速器在低擋換擋的時候頓挫感比較明顯。

以上三款車都是所推薦的兩廂車,綜合實力來說都是比較強的,各位看官可以根據自己的需求來挑選喲!本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

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

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

※回頭車貨運收費標準

初識Redis的數據類型HyperLogLog

前提

未來一段時間開發的項目或者需求會大量使用到Redis,趁着這段時間業務並不太繁忙,抽點時間預習和複習Redis的相關內容。剛好看到博客下面的UVPV統計,想到了最近看書裏面提到的HyperLogLog數據類型,於是花點時間分析一下它的使用方式和使用場景(暫時不探究HyperLogLog的實現原理)。RedisHyperLogLog數據類型是Redid 2.8.9引入的,使用的時候確保Redis版本>= 2.8.9

HyperLogLog簡介

基數計數(cardinality counting),通常用來統計一個集合中不重複的元素個數。一個很常見的例子就是統計某個文章的UVUnique Visitor,獨立訪客,一般可以理解為客戶端IP)。大數據量背景下,要實現基數計數,多數情況下不會選擇存儲全量的基數集合的元素,因為可以計算出存儲的內存成本,假設一個每個被統計的元素的平均大小為32bit,那麼如果統計一億個數據,佔用的內存大小為:

  • 32 * 100000000 / 8 / 1024 / 1024 ≈ 381M

如果有多個集合,並且允許計算多個集合的合併計數結果,那麼這個操作帶來的複雜度可能是毀滅性的。因此,不會使用BitmapTree或者HashSet等數據結構直接存儲計數元素集合的方式進行計數,而是在不追求絕對準確計數結果的前提之下,使用基數計數的概率算法進行計數,目前常見的有概率算法以下三種:

  • Linear Counting(LC)
  • LogLog Counting(LLC)
  • HyperLogLog Counting(HLL)

所以,HyperLogLog其實是一種基數計數概率算法,並不是Redis特有的,Redis基於C語言實現了HyperLogLog並且提供了相關命令API入口。

Redis的作者Antirez為了紀念Philippe Flajolet對組合數學和基數計算算法分析的研究,所以在設計HyperLogLog命令的時候使用了Philippe Flajolet姓名的英文首字母PF作為前綴。也就是說,Philippe Flajolet博士是HLL算法的重大貢獻者,但是他其實並不是RedisHyperLogLog數據類型的開發者。遺憾的是Philippe Flajolet博士於2011年3月22日因病在巴黎辭世。這個是Philippe Flajolet博士的維基百科照片:

Redis提供的HyperLogLog數據類型的特徵:

  • 基本特徵:使用HyperLogLog Counting(HLL)實現,只做基數計算,不會保存元數據
  • 內存佔用:HyperLogLog每個KEY最多佔用12K的內存空間,可以計算接近2^64個不同元素的基數,它的存儲空間採用稀疏矩陣存儲,空間佔用很小,僅僅在計數基數個數慢慢變大,稀疏矩陣佔用空間漸漸超過了閾值時才會一次性轉變成稠密矩陣,轉變成稠密矩陣之後才會佔用12K的內存空間。
  • 計數誤差範圍:基數計數的結果是一個標準誤差(Standard Error)為0.81%的近似值,當數據量不大的時候,得到的結果也可能是一個準確值。

內存佔用小(每個KEY最高佔用12K)是HyperLogLog的最大優勢,而它存在兩個相對明顯的限制:

  • 計算結果並不是準確值,存在標準誤差,這是由於它本質上是用概率算法導致的。
  • 不保存基數的元數據,這一點對需要使用元數據進行數據分析的場景並不友好。

HyperLogLog命令使用

Redis提供的HyperLogLog數據類型一共有三個命令APIPFADDPFCOUNTPFMERGE

PFADD

PFADD命令參數如下:

PFADD key element [element …]

支持此命令的Redis版本是:>= 2.8.9
時間複雜度:每添加一個元素的複雜度為O(1)

  • 功能:將所有元素參數element添加到鍵為keyHyperLogLog數據結構中。

PFADD命令的執行流程如下:

PFADD命令的使用方式如下:

127.0.0.1:6379> PFADD food apple fish
(integer) 1
127.0.0.1:6379> PFADD food apple
(integer) 0
127.0.0.1:6379> PFADD throwable
(integer) 1
127.0.0.1:6379> SET name doge
OK
127.0.0.1:6379> PFADD name throwable
(error) WRONGTYPE Key is not a valid HyperLogLog string value.

雖然HyperLogLog數據結構本質是一個字符串,但是不能在String類型的KEY使用HyperLogLog的相關命令。

PFCOUNT

PFCOUNT命令參數如下:

PFCOUNT key [key …]

支持此命令的Redis版本是:>= 2.8.9
時間複雜度:返回單個HyperLogLog的基數計數值的複雜度為O(1),平均常數時間比較低。當參數為多個key的時候,複雜度為O(N),N為key的個數。

  • PFCOUNT命令使用單個key的時候,返回儲存在給定鍵的HyperLogLog數據結構的近似基數,如果鍵不存在, 則返回0
  • PFCOUNT命令使用key的時候,返回儲存在給定的所有HyperLogLog數據結構的並集的近似基數,也就是會把所有的HyperLogLog數據結構合併到一個臨時的HyperLogLog數據結構,然後計算出近似基數。

PFCOUNT命令的使用方式如下:

127.0.0.1:6379> PFADD POST:1 ip-1 ip-2
(integer) 1
127.0.0.1:6379> PFADD POST:2 ip-2 ip-3 ip-4
(integer) 1
127.0.0.1:6379> PFCOUNT POST:1
(integer) 2
127.0.0.1:6379> PFCOUNT POST:1 POST:2
(integer) 4
127.0.0.1:6379> PFCOUNT NOT_EXIST_KEY
(integer) 0

PFMERGE

PFMERGE命令參數如下:

PFMERGE destkey sourcekey [sourcekey ...]

支持此命令的Redis版本是:>= 2.8.9
時間複雜度:O(N),其中N為被合併的HyperLogLog數據結構的數量,此命令的常數時間比較高

  • 功能:把多個HyperLogLog數據結構合併為一個新的鍵為destkeyHyperLogLog數據結構,合併后的HyperLogLog的基數接近於所有輸入HyperLogLog的可見集合(Observed Set)的並集的基數。
  • 命令返回值:只會返回字符串OK

PFMERGE命令的使用方式如下

127.0.0.1:6379> PFADD POST:1 ip-1 ip-2
(integer) 1
127.0.0.1:6379> PFADD POST:2 ip-2 ip-3 ip-4
(integer) 1
127.0.0.1:6379> PFMERGE POST:1-2 POST:1 POST:2
OK
127.0.0.1:6379> PFCOUNT POST:1-2
(integer) 4

使用HyperLogLog統計UV的案例

假設現在有個簡單的場景,就是統計博客文章的UV,要求UV的計數不需要準確,也不需要保存客戶端的IP數據。下面就這個場景,使用HyperLogLog做一個簡單的方案和編碼實施。

這個流程可能步驟的先後順序可能會有所調整,但是要做的操作是基本不變的。先簡單假設,文章的內容和統計數據都是後台服務返回的,兩個接口是分開設計。引入Redis的高級客戶端Lettuce依賴:

<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>

編碼如下:

public class UvTest {

    private static RedisCommands<String, String> COMMANDS;

    @BeforeClass
    public static void beforeClass() throws Exception {
        // 初始化Redis客戶端
        RedisURI uri = RedisURI.builder().withHost("localhost").withPort(6379).build();
        RedisClient redisClient = RedisClient.create(uri);
        StatefulRedisConnection<String, String> connect = redisClient.connect();
        COMMANDS = connect.sync();
    }

    @Data
    public static class PostDetail {

        private Long id;
        private String content;
    }

    private PostDetail selectPostDetail(Long id) {
        PostDetail detail = new PostDetail();
        detail.setContent("content");
        detail.setId(id);
        return detail;
    }

    private PostDetail getPostDetail(String clientIp, Long postId) {
        PostDetail detail = selectPostDetail(postId);
        String key = "puv:" + postId;
        COMMANDS.pfadd(key, clientIp);
        return detail;
    }

    private Long getPostUv(Long postId) {
        String key = "puv:" + postId;
        return COMMANDS.pfcount(key);
    }

    @Test
    public void testViewPost() throws Exception {
        Long postId = 1L;
        getPostDetail("111.111.111.111", postId);
        getPostDetail("111.111.111.222", postId);
        getPostDetail("111.111.111.333", postId);
        getPostDetail("111.111.111.444", postId);
        System.out.println(String.format("The uv count of post [%d] is %d", postId, getPostUv(postId)));
    }
}

輸出結果:

The uv count of post [1] is 4

可以適當使用更多數量的不同客戶端IP調用getPostDetail(),然後統計一下誤差。

題外話-如何準確地統計UV

如果想要準確統計UV,則需要注意幾個點:

  • 內存或者磁盤容量需要準備充足,因為就目前的基數計數算法來看,沒有任何算法可以在不保存元數據的前提下進行準確計數。
  • 如果需要做用戶行為分析,那麼元數據最終需要持久化,這一點應該依託於大數據體系,在這一方面筆者沒有經驗,所以暫時不多說。

假設在不考慮內存成本的前提下,我們依然可以使用Redis做準確和實時的UV統計,簡單就可以使用Set數據類型,增加UV只需要使用SADD命令,統計UV只需要使用SCARD命令(時間複雜度為O(1),可以放心使用)。舉例:

127.0.0.1:6379> SADD puv:1 ip-1 ip-2
(integer) 2
127.0.0.1:6379> SADD puv:1 ip-3 ip-4
(integer) 2
127.0.0.1:6379> SCARD puv:1
(integer) 4

如果這些統計數據僅僅是用戶端展示,那麼可以採用異步設計:

在體量小的時候,上面的所有應用的功能可以在同一個服務中完成,消息隊列可以用線程池的異步方案替代。

小結

這篇文章只是簡單介紹了HyperLogLog的使用和統計UV的使用場景。總的來說就是:在(1)原始數據量巨大,(2)內存佔用要求盡可能小,(3)允許計數存在一定誤差並且(4)不要求存放元數據的場景下,可以優先考慮使用HyperLogLog進行計數。

參考資料:

  • antirez-Redis new data structure: the HyperLogLog
  • Redis Commands
  • 維基百科

(本文完 c-3-d e-a-20191117)

技術公眾號(《Throwable文摘》),不定期推送筆者原創技術文章(絕不抄襲或者轉載):

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

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

【Spring註解驅動開發】面試官:如何將Service注入到Servlet中?朋友又栽了!!

寫在前面

最近,一位讀者出去面試前準備了很久,信心滿滿的去面試。沒想到面試官的一個問題把他難住了。面試官的問題是這樣的:如何使用Spring將Service注入到Servlet中呢?這位讀者平時也是很努力的,看什麼源碼啊、多線程啊、高併發啊、設計模式啊等等。沒想到卻在一個很簡單的問題上栽了跟頭,這就說明學習知識要系統化,要有條理,切忌東學一點,西記一點,否則,到頭來,啥也學不到。

項目工程源碼已經提交到GitHub:https://github.com/sunshinelyz/spring-annotation

如何實現將Service注入到Servlet中??

這裏,我們列舉兩種解決方法(推薦使用第二種)

方法一:

直接重寫Servlet的Init()方法,代碼如下:

public void init(ServletConfig servletConfig) throws ServletException {
	ServletContext servletContext = servletConfig.getServletContext();
	WebApplicationContext webApplicationContext = WebApplicationContextUtils
			.getWebApplicationContext(servletContext);
	AutowireCapableBeanFactory autowireCapableBeanFactory = webApplicationContext
			.getAutowireCapableBeanFactory();
	autowireCapableBeanFactory.configureBean(this, BEAN_NAME);
}

這裏的BEAN_NAME即為我們需要注入到Spring容器中的服務,但這並不是一個好的方法,因為我們需要在每一個Servlet中都進行這樣的操作。

方法二:

我們可以寫一個類似於“org.springframework.web.struts.DelegatingRequestProcessor”的委託的Bean,然後通過配置的方法把我們的服務注入到servlet中,具體方法如下,

Step 1:編寫委託類DelegatingServletProxy

package com.telek.pba.base.util;

import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 * 以下是類似org.springframework.web.struts.DelegatingRequestProcessor的一個委託
 * 用於通過配置的方法,在Servlet中注入Service
 * @author binghe
 * */
public class DelegatingServletProxy extends GenericServlet{
    private static final long serialVersionUID = 1L;
    private String targetBean;
    private Servlet proxy;

   @Override
   public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException{
   		proxy.service(req, res);
   }
     /**
      * 初始化
      */
      public void init() throws ServletException {
          this.targetBean = getServletName();
          getServletBean();
          proxy.init(getServletConfig());
      }

     /**
      * 獲取Bean
      */
      private void getServletBean() {
          WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
          this.proxy = (Servlet) wac.getBean(targetBean);
      }
}

Step 2:修改Web.xml配置

在純Servlet模式下,我們的配置方式如下(以下由於代碼高亮插件的問題,請將代碼中的#替換成尖括號)

<servlet>
  <description>活動發起模塊活動查詢分頁Servlet</description>
  <display-name>launchActivityQueryServlet</display>
  <servlet-name>LaunchActivityQueryServlet</servlet-name>
  <servlet-class>com.telek.pba.launch.servlet.LaunchActivityQueryServlet</servlet-class>
<servlet>

<servlet-mapping>
  <servlet-name>LaunchActivityQueryServlet</servlet-name>
  <url-pattern>/servlet/launch/LaunchActivityQueryServlet</url-pattern>
</servlet-mapping>
</servlet>

如果採用我們這種代理的方法,則配置應該修改為:

<servlet>
  <description>活動發起模塊活動查詢分頁Servlet</description>
  <display-name>launchActivityQueryServlet</display>
  <servlet-name>launchActivityQueryServlet</servlet-name>
  <servlet-class>com.telek.pba.base.util.DelegatingServletProxy</servlet-class>
<servlet>

<servlet-mapping>
  <servlet-name>launchActivityQuery</servlet-name>
  <url-pattern>/servlet/launch/LaunchActivityQueryServlet</url-pattern>
</servlet-mapping>
</servlet> 

注意:默認情況下,Servlet的配置中,LaunchActivityQuery的首字母一般為大寫,而我們的標題中已註明,我們採用Spring的註解模式,如果是自動掃描註解的話,默認情況下,註解的value值為首字母小寫,即:launchActivityQuery,因此,在我們新的配置中,要注意將首字母改為小寫,否則會報無法找到Bean的錯誤。

Step 3:至此,我們就可以像SSH的注入方式一樣,注入Servlet了,以下是個小示例:

package com.telek.pba.launch.servlet;

import java.io.IOException;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import com.telek.pba.base.model.PbaUserInfo;
import com.telek.pba.launch.dao.IPbaActivityInfoCurrentDAO;

@Component
public class LaunchActivityQueryServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	 
	//注入IPbaActivityInfoCurrentDAO
	@Resource
	private IPbaActivityInfoCurrentDAO pbaActivityInfoCurrentDAO;

	public LaunchActivityQueryServlet() {
		super();
	}
	 
	public void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		// Put your code here
	}
	 
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//sth to do
	}
	 
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//sth to do
	}
	 
	public void init() throws ServletException {
		// Put your code here
	}
}

最後,請留心在Spring配置文件中,配置上自動掃描包的路徑:

<context:component-scan base-package="com.telek.pba.*.dao.impl,
 					com.telek.pba.*.service.impl,
 					com.telek.pba.*.servlet"/>

大功告成!

好了,咱們今天就聊到這兒吧!別忘了給個在看和轉發,讓更多的人看到,一起學習一起進步!!

項目工程源碼已經提交到GitHub:https://github.com/sunshinelyz/spring-annotation

寫在最後

如果覺得文章對你有點幫助,請微信搜索並關注「 冰河技術 」微信公眾號,跟冰河學習Spring註解驅動開發。公眾號回復“spring註解”關鍵字,領取Spring註解驅動開發核心知識圖,讓Spring註解驅動開發不再迷茫。

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

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

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

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

※回頭車貨運收費標準

升溫不超過2°C的變數 全球農業氮肥「一氧化二氮預算」首出爐

環境資訊中心外電;姜唯 翻譯;林大利 審校;稿源:Carbon Brief

Carbon Brief報導,根據全球碳計畫(Global Carbon Project)的研究,全世界用於生產糧食的氮肥,可能會使全球升溫2°C以內的氣候目標更難達成。

全世界用於生產糧食的氮肥,可能會使全球升溫2°C以內的氣候目標更難達成。照片來源:StateofIsrael(CC BY 2.0)

40年來人為的一氧化二氮排放增加了30%

全球碳計畫探討一氧化二氮(N2O)排放如何加劇氣候變遷,進行首次的全面性評估。研究結果發現,過去40年間,人類產生的一氧化二氮排放增加了30%,主要原因是農業使用。

肉類和奶製品需求成長也是重要推手,因為牲畜糞便會導致一氧化二氮排放,而且氮肥通常也用於生產動物飼料。

其中人類產生的一氧化二氮排放量成長極快的國家包括巴西、中國和印度。

一氧化二氮排放趨勢與氣候目標 兩者途徑不相容

一氧化二氮是能夠長期存在大氣中的溫室氣體,就100年為期來看,能耐是二氧化碳的300倍,僅次於二氧化碳和甲烷,是氣候變遷的第三大貢獻者。

氣體透過各種自然過程釋放到大氣中,包括土壤和海洋中微生物的活動。有些自然過程,包括平流層和對流層中的化學反應,則會減少一氧化二氮排放。

但是,人類活動也會導致一氧化二氮進入大氣。人類產生的一氧化二氮排放主要來自農業,化石燃料業和生質燃燒也會產生,但影響較小。

新研究探討2007至2016年所有排放一氧化二氮排放的方式,包括人類活動和自然過程,以計算出全球首個「一氧化二氮預算」。

奧本大學國際氣候與全球變遷研究中心主任田漢勤教授說,研究結果顯示,除非採取行動去抑制,否則人為一氧化二氮排放可能影響巴黎協定全球暖化遠低於2°C的目標。「研究結果最令人驚訝的發現是,當前一氧化二氮排放趨勢與實現巴黎協定氣候目標的可能途徑不相容。」

人為一氧化二氮排放 大部分來自農業中的氮肥

2007至2016年間,全球一氧化二氮排放量平均每年淨增加430萬噸,包括自然和人為來源產生的排放。

同一時間,人為一氧化二氮排放量成長30%,上升到每年730萬噸,其中一半以上來自提高農業產量的氮肥。

根據2019年政府間氣候變遷專門委員會(IPCC)發表的氣候變遷和土地報告,自1961年以來,全球農業肥料的使用量增加了9倍。

此外,肉類和奶製品需求不斷成長也是農業排放量增加的原因。「肉類和奶製品需求持續成長、牧場草地擴張,全球牲畜糞便生產和管理相關的一氧化二氮排放量也隨之大增。」

研究顯示,自1980年代以來,農業一氧化二氮排放量在東亞和南亞、南美和非洲的成長最快。同時,北美的農業一氧化二氮排放一直維持高水準,而歐洲的農業一氧化二氮排放則有小幅下降。

一氧化二氮排放量與氣候變遷可能情境比較

科學家也將目前一氧化二氮排放量與未來兩種氣候變遷可能情境中的排放量做比較,分別是「代表性濃度途徑(RCPs)」和「共享社會經濟途徑(SSPs)」。

下圖A顯示了全球一氧化二氮排放量與RCPs預測排放量相比。圖C是全球一氧化二氮濃度與RCPs預測濃度的比較。(在RCP2.6的假設情境下,全世界成功將全球暖化限制在2°C以下,RCP8.5則是排放量非常高的假設情境,在這個情境下,本世紀末溫度可能升高約4.3°C或更多。)

圖B顯示全球一氧化二氮排放量與SSPs的預測排放量的比較,而圖D顯示全球一氧化二氮濃度與SSPs的預測濃度的比較。(SSP3是各國在氣候行動上幾乎沒有合作的假設情境,SSP1是世界一同聚焦實現氣候目標的假設情境。)

圖上黑線是平均一氧化二氮排放量,藍色虛線是「自下而上」(bottom-up)估算值,以國家資料為基礎,黃色虛線是「自上而下」(top-down)估算值,以全球模型和衛星資料為基礎。

歷年與預測的一氧化二氮(N2O)排放(A,B)和濃度(C,D)趨勢圖。圖片來源:
Tian et al. (2020)

結果,目前一氧化二氮排放與高排放情境(RCP8.5)相符,並高過所有的SSPs情境。

研究作者、澳洲聯邦科學與工業研究組織(CSIRO)氣候研究中心首席科學家、全球碳計畫執行董事康納戴爾(Pep Canadell)博士說,這表示要將全球暖化限制在2°C以下,未來的幾十年需要迅速減少一氧化二氮排放。

「要種出能養活我們的大量糧食,全球糧食系統免不了會排放一些一氧化二氮,但是我們必須大幅提高使用效率來減少排放。」康納戴爾博士說。

未參與研究的阿伯丁大學植物和土壤科學系主任史密斯(Pete Smith)教授說,這表示全世界需要改變飲食習慣因應氣候變遷。 「我們必須找到更有效率的糧食生產方法,同時降低氮的用量和每單位產品的排放量。 我們還必須重新設計糧食體系,使其減少依賴肉類和奶製品等效率低下的糧食供應鏈,並顯著減少糧食浪費,在地球可負荷範圍內養活我們所有人。」

Nitrogen fertiliser use could ‘threaten global climate goals’ by DAISY DUNNE

The world’s use of nitrogen fertilisers for food production could threaten efforts to keep global warming below 2C above pre-industrial levels.

That is according to the Global Carbon Project’s first comprehensive assessment of how nitrous oxide (N2O) emissions are contributing to climate change.

Published in Nature, the results show that human-caused N2O emissions have increased by 30% over the past four decades – with the use of nitrogen fertilisers in agriculture playing a major role in the uptick.

A growing demand for meat and dairy products has also contributed to the surge. This is because livestock manure causes N2O emissions and nitrogen fertilisers are often used in the production of animal feed, the scientists say.

The countries with the fastest growing human-caused N2O emissions include Brazil, China and India, the research adds.

Potent pollutant

N2O is a long-lived greenhouse gas that is almost 300 times more potent than CO2 over a 100-year period. It is the third-largest contributor to climate change after CO2 and methane.

The gas is released into the atmosphere by various natural processes, including through the activity of microbes in soils and oceans. Other natural processes, including chemical reactions in the stratosphere and troposphere, cause a reduction in N2O emissions.

However, human activities can also cause N2O to be released into the atmosphere. Human-caused N2O emissions chiefly come from agriculture, with the fossil-fuel industry and biomass burning also contributing to a lesser degree.

The new assessment considered all the ways in which human activities and natural processes contributed to N2O emissions from 2007-16 in order to produce the first global “N2O budget”.

The findings show that, unless curbed, human-caused N2O emissions could threaten the Paris Agreement’s target of keeping global warming “well below” 2C, says lead author Prof Hanqin Tian, director of the International Center for Climate and Global Change Research at Auburn University in Alabama. He tells Carbon Brief:

“The most surprising result of the study was the finding that current trends in N2O emissions are not compatible with pathways consistent to achieve the climate goals of the Paris Agreement.”

First budget

The infographic below, which was produced by the Global Carbon project, summarises the findings. On the infographic, orange arrows show human-caused N2O emissions while green arrows show natural N2O emissions. A blue arrow indicates the reduction in N2O emissions provided by chemical reactions in the upper atmosphere (“atmospheric chemical sink”).

The infographic shows that global N2O emissions increased by a net 4.3m tonnes a year, on average, from 2007-16. This figure includes N2O emissions from both natural and human-caused sources.

In that time, human-caused N2O emissions rose to 7.3m tonnes per year. This is 30% higher than four decades ago, the study says.

More than half of human-caused N2O emissions come from agriculture. The main driver of these emissions are nitrogen fertilisers, which are routinely sprayed overfood crops in order to boost yields.

Fertiliser application on crops has increased nine-fold worldwide since 1961, according to a recent landmark report on land and climate change from the Intergovernmental Panel on Climate Change (IPCC) released in 2019.

However, a growing demand for meat and dairy products is also a driver of increasing agricultural emissions, the researchers say in their paper:

“Growing demand for meat and dairy products has substantially increased global N2O emissions from livestock manure production and management associated with the expansion of pastures and grazing land.”

The assessment shows that, since the 1980s, agricultural N2O emissions have been rising the fastest in East and South Asia, South America and Africa.

Meanwhile, agricultural N2O emissions in North America have stayed consistently high, while Europe has seen a small dip in its agricultural N2O emissions.
Outpaced

As part of their analysis, the scientists explored how current N2O emissions compare with those from the scenarios used to make future projections about climate change.

These include the “Representative Concentration Pathways” (RCPs) and the “Shared Socioeconomic Pathways” (SSPs). 

Chart A below shows how global N2O emissions compare with projected emissions from the RCPs. Chart C, meanwhile, shows how global concentrations of N2O compare to projected concentrations from the RCPs.

(RCP2.6 is a scenario where the world successfully limits global warming to below 2C, whereas RCP8.5 is a scenario of very high emissions, where temperatures could rise by around 4.3C or more by the end of the century.)

Chart B shows how global N2O emissions compare with projected emissions from the SSPs, while chart D shows how global concentrations of N2O compare to projected concentrations from the SSPs.

(SSP3 is a scenario where countries do little to cooperate on climate action, whereas SSP1 is a scenario where the world shifts its focus to meeting climate targets.)

On the charts, the black line shows average N2O emissions, whereas the blue line shows “bottom-up” estimates and the yellow line shows “top-down” estimates. (Bottom-up estimates are based on country inventory data, whereas top-up estimates are obtained from global models and satellite data.)

in order to limit global warming to below 2C, N2O emissions will need to be rapidly reduced in the coming decades, explains study author Dr Pep Canadell, chief research scientist at the Commonwealth Scientific and Industrial Research Organisation (CSIRO) Climate Research Centre in Australia and executive director of the Global Carbon Project. He tells Carbon Brief:

“The global food system will always leak some N2O given there are no alternatives to nitrogen fertiliser for growing so much of the food we eat. However, we must become much more efficient in the way we use it, which will lead to significant emission reductions.”

The findings reinforce the message that the world needs to change its eating habits in order to tackle climate change, says Prof Pete Smith, chair of plant and soil science at the University of Aberdeen, who was not involved in the research. He tells Carbon Brief:

“The study underlines that we must find more efficient ways of producing food, with lower nitrogen inputs and emissions per unit of product. But also, we must redesign our current food system so that it can feed us all within ‘planetary boundaries’ by reducing reliance on inefficient supply chains such as meat and dairy and by dramatically reducing food waste.”

※ 全文及圖片詳見:Carbon BriefCC BY-NC-ND 4.0

參考資料

氮肥
一氧化二氮
溫室氣體
升溫
動物飼料
農林漁牧業
國際新聞
氣候變遷

作者

姜唯

如果有一件事是重要的,如果能為孩子實現一個願望,那就是人類與大自然和諧共存。

林大利

於特有生物研究保育中心服務,小鳥和棲地是主要的研究對象。是龜毛的讀者,認為龜毛是探索世界的美德。

延伸閱讀

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

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

吉力馬札羅山山坡大火 坦尚尼亞消防員連日撲救

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

東非國家坦尚尼亞官員表示,消防員連續第3天與吉力馬札羅山(Mount Kilimanjaro)山坡上的大火對抗,希望控制這座非洲第一高峰的火勢。

路透社報導,大火11日起於胡娜區(Whona),強風助長了火勢,官員表示,風勢今天已經減弱。胡娜區是使用曼達拉(Mandara)和霍倫坡(Horombo)兩條登山路線的登山客的休息中心。

坦尚尼亞國家公園管理局(TANAPA)官員謝魯特(Pascal Shelutete)向路透社表示,消防員與相關人員正努力控制火勢,並稱火勢已「幾乎獲遏止」。

氣候變遷
國際新聞
坦尚尼亞
吉力馬扎羅山
大火

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

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

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

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

※回頭車貨運收費標準

白菜價,這3款合資緊湊SUV最低11萬,你還選國產車嗎?

內飾雖然不如外觀張揚個性,但設計感要比逍客強,並且在用料方面更優一些,中控大部分以軟性材料為主,並用以縫線做點綴。全液晶儀錶為全系標配,可開啟的全景天窗相比逍客的玻璃車頂更為實用,而在乘坐空間表現方面,兩者則差別不大。

在這碩大的汽車消費市場中,還是存在不少合資車擁躉,他們會覺得合資車更加成熟穩定,並且相比自主品牌更顯面子;那對於那些想隨SUV大流,預算只有十多萬的小夥伴來說,能買到哪些在體型、空間上可觀,開出去又不輸面子的合資SUV呢?下面跟着來看一下吧。

東風日產-逍客

上代逍客作為這個細分市場的開創者之一,憑藉著自身不錯的品質以及較為合理的售價,一經上市就取得了傲人的成績;這代車型於2015年上市,把原本稍顯圓潤的外形變得動感犀利,簡約直接的線條設計讓整個外形顯得耐看,甚至不會讓人覺得有過時感。

內飾設計和奇駿相似度極高,整體中規中矩,功能布局清晰,設計風格沒有什麼亮點,做工用料處於同級的中上游水平,後排空間只是夠用水平,不過座椅繼承了日產的特點,舒適性和柔軟度都不錯。

相比以往傳統的日產家用車,逍客的整體懸挂調校會偏硬一些,且擁有一定的韌性,反應也更為靈活;日常的舒適性還算不錯,不過在遇到較大的溝坎路面或減速帶時,懸挂會出現多餘的跳動,而且在高速過彎時的側傾較為明顯;方向盤虛位感明顯,指向也算不上精準。

東風雷諾-科雷嘉

作為逍客的孿生兄弟,晚些出生的科雷嘉在外觀方面充斥着滿滿的法式設計元素,整體線條更為活潑靈動,視覺效果圓潤飽滿,比逍客更顯壯實;外觀細節例如科技感十足的全LED頭燈、造型立體的尾燈等等,都設計得比逍客更顯精緻用心。

內飾雖然不如外觀張揚個性,但設計感要比逍客強,並且在用料方面更優一些,中控大部分以軟性材料為主,並用以縫線做點綴;全液晶儀錶為全系標配,可開啟的全景天窗相比逍客的玻璃車頂更為實用,而在乘坐空間表現方面,兩者則差別不大。

科雷嘉整體的駕駛風格和逍客接近,日常都是以追求穩定舒適為主,不過偏硬的懸挂設定,在過坎時處理不算從容,而且對多餘振動的抑制效果一般,但整體表現出的質感還是略好於逍客。

北京現代-ix35

全新ix35在外觀方面的變化可謂是巨大,原本流暢的外形變得方正硬朗,頗有一些硬派越野車的意思,整體顯得更“man”,安全感更足。

中控設計風格與外觀有所呼應,造型硬朗簡約,有着不錯的視覺質感,並且各功能分區布局清晰,容易上手,用料上則沒給人什麼驚喜,多為硬質材質,觸感一般;不過在空間方面表現不錯,並且後排中間地台凸起不算高,稍有遺憾的是全景天窗全系都沒有配備,在開揚感方面遜於對手。

ix35的懸挂遇到小的顛簸可以很從容地過濾掉,有着不錯的舒適性與質感,但遇到大的坑窪路面處理起來就沒那麼乾脆自然,懸挂會出現多餘的彈跳外,還伴隨着車身明顯的晃動,不過整體底盤的表現還算屬於這個級別的主流水準。

各地優惠參考

在優惠幅度方面,ix35的是最少的,而科雷嘉相比胞兄逍客有着稍多一些的優惠,總體來看,三者優惠后的最終成交價格相對接近。

總結

逍客和科雷嘉都是同平台的雙胞胎車型,逍客有着更高的品牌知名度,科雷嘉則在設計上有着自己獨特的表達方式,並且配置用料表現要更好一些;而ix35有着更顯硬朗的外觀和得體的空間表現;三者你會作出怎樣的選擇呢?歡迎在下方留言喔!本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

哈弗H6最強對手換代,天窗無敵,內飾升級,9.98萬你買嗎?

值得一提的是,全景影像四攝像頭還具備行車記錄儀功能,防護功能遠勝傳統行車記錄儀。此外,法國法雷奧一鍵泊車系統(12顆超聲波雷達)、鑰匙遙控泊車等功能在同級更是前所未見,勇氣可嘉。配置方面,前排座椅加熱、通風和空調功能被集成至排擋桿前方的獨立觸控屏上,估計出於成本控制輕觸后未見震動反饋,增加了盲操學習成本,所幸保留了聲音反饋。

滿足小有成就的現狀,缺乏居安思危意識,是營銷領域中不少先鋒產品的通病。等恍悟備受衝擊、該有所行動時,卻被時代洪流淹沒的例子,比比皆是。

(老款CS75)

上市四年以來,長安CS75無論在群眾口碑抑或銷量方面,都頗有建樹。隨着時間推移、消費升級,外觀和內飾開始顯得落伍、俗套。為了喚起潛在買家熱情,中期改款CS75厲兵秣馬、煥新而來。

全新CS75能否追隨自主SUV往上發展、實現高端化的潮流?身體力行前往世外桃源香格里拉,一試究竟。

外觀設計

長安睿騁CC砍獲德國紅點設計大獎后名噪一時,飄逸流暢的蝶翼式前臉讓長安轎車產品觀感度躍升一個維度。這份美好卻未能沿襲至全新CS75上,引以為憾。

所幸的是,新款CS75內外設計均往积極方向在推進。外觀一改老款地盤包工頭的“油膩”印象,大量的橫向鍍鉻飾條強調年輕化,比頗具爭議的“CHANGAN”字母臉強不止一星半點。

車燈儼然成為時下車型外觀設計的重中之重,深諳於此的長安為新款CS75換裝帶自動大燈功能的全LED大燈,造型犀利、燈腔內部精緻,跟來車怒目相視的感覺。

箭羽造型的霧燈區域安放在前包圍左右兩側,LED轉向燈帶巧妙地鑲嵌其上,內凹線條的勾勒對運動感的提升大有裨益,成功化解“中年危機”。

新款車型配有ACC自適應巡航功能,車頭底部的模塊能窺探一二,較強的塑料感缺乏精緻度。

車身尺寸與舊款別無二致,長/寬/高:4650/1850/1705mm,軸距:2700mm。側腰線條平鋪直敘、寬厚瓷實,屬四平八穩的類型。

后視鏡集成了轉向燈,從底部的攝像頭和鏡面標識可知,新款高配車型配備了盲區監測功能和全景影像。

試駕車型選用19英寸雙色鋁合金輪圈,與之搭配的是優科豪馬GEOLANDAR G91輪胎(225/55 R19),為四驅輪胎開發的獨特胎面膠配方,溝槽設計主打濕地操控、制動性能,乾地制動表現一般。

自主SUV一窩蜂玩壞了懸浮式車頂、碩大英文尾標后,又將魔爪伸向了當年林肯MKZ敢為人先的貫穿式尾燈。不出多久,貫穿式尾燈會淪為自主SUV中俗套的設計元素。

選用貨真價實的雙出排氣布局,扁平排氣口造型不落窠臼,與反光帶、尾燈造型遙相呼應,呈現出整體感喜人的尾部輪廓。

內飾配置

與外觀一樣,全新CS75的內飾表現出足夠的革新度和顛覆感,舊款內飾的鄉村氣息黯晦消沉,取而代之的是與時俱進的內飾氛圍。

軟質材料應用廣泛,多處的單雙縫線交替,方寸之間,盡顯品位。新車內飾供科技黑和輕奢棕兩色可選,後者配備仿木紋材料更是時刻在強調檔次感。

10.25英寸全液晶儀錶盤、10.25英寸懸浮式觸控屏、电子擋桿、平底方向盤、大面積的鋼琴烤漆面板、七色氛圍燈對車內質感的提升大有裨益。

其中試駕車型的10.25英寸懸浮式觸控屏配備全景影像和虛擬影像功能,显示效果細膩,提供優良閱讀效果,可謂女司機福音。

以配置水平見長的自主車,無鑰匙進入/啟動功能自然必備必不可少,全系標配德爾福STT智能啟停功能,優化燃油經濟性。

遠不止此,強調科技感的全液晶儀錶盤能與中控大屏實現雙屏互動,導航、ACC全速自適應巡航(0-150km/h)等信息同樣能呈現於儀錶盤,甚是方便。

值得一提的是,全景影像四攝像頭還具備行車記錄儀功能,防護功能遠勝傳統行車記錄儀。此外,法國法雷奧一鍵泊車系統(12顆超聲波雷達)、鑰匙遙控泊車等功能在同級更是前所未見,勇氣可嘉。

配置方面,前排座椅加熱、通風和空調功能被集成至排擋桿前方的獨立觸控屏上,估計出於成本控制輕觸后未見震動反饋,增加了盲操學習成本,所幸保留了聲音反饋。

溫度調節和吹風模式保留實體按鍵,長安工程師對人機工程學的考究是可感知的。但如何改善光滑面板的反光現象,會是道不小的難題。

最為人稱道的當屬換裝电子擋桿,採用輕觸方式激活p擋的方式同級罕見,但使用體驗有待商榷,需要適應一段時間。

貴為長安產品矩陣中的銷量擔當,新款CS75僅前排車窗支持一降升降功能,為車內乘員日常啟閉車窗增添不便,不應當,扣分項。

空間表現

國人喜聞樂見的全景天窗如常出席,1.12平方米的採光面積(同級最大)有效拉升乘員的暈車閾值。輔以靠背支持多角度調節的後排座椅以及接近純平的後排中央地板,絕對是說服長輩掏包的有力論證。

整體空間表現絲毫不怵主流中型SUV水準,不易聽到乘員的抱怨聲。手套箱、扶手箱足以安放常規單反相機,擋桿前方、杯架、四門門把手處的儲物格均能容納大尺寸智能手機,實屬難得。

此外,後排座椅安全帶卡扣可收折,不磕屁股。後排座椅支持4/6分割放倒,放倒後接近純平狀態,宜商宜居。

動態表現

新款CS75搭載全新藍鯨 280T 直噴增壓發動機,這枚1.5T發動機在德爾福高壓共軌直噴系統、霍尼韋爾增強脈衝渦輪增壓器、水冷中冷的加持下,最大馬力178ps/5500rpm、峰值扭矩265N·m/1450-4500rpm,官宣百公里加速時間為10s,搭配日本愛信第三代6AT。

此前舊款CS75機油增多事件牽動不少潛在買家的心,而全新CS75搭載的發動機選用全新的噴油方案以及熱管理系統,暖機時間較此前縮短近2min,輔以重新調校的ECU程序,各位無需過慮。

起步階段存有“起床氣”,若不將油門踩得比預期稍深,車輛更願意停留在慵懶狀態。高速下再深踩油門,引擎艙發出歇斯底里的嘶吼聲,小排量渦輪增壓的單薄感被進一步放大。

變速箱齒比設定綿密,3擋開始便能實現閉鎖控制,對動力輸出的連續性、降低動力損耗等大有裨益。升擋后發動機轉速小幅回落,努力維持在峰值扭矩輸出區間,兢兢業業地保持加速力道。至於推背感嘛,沒有。

剎車前半段虛位較大,制動力輸出不夠線性,日常市區行駛不易形成輕鬆駕駛氛圍。更青睞一點就有、漸進式的剎車腳感,還望廠商後期優化。

新車選用前麥弗遜、后多連桿獨立懸架結構,配備美國天納克MTV-CL減震器閥系,彈簧K值較同級家用SUV高,在面對坑窪、起伏路面時動作稍顯敏感。重心轉移與駕駛員預期不夠默契,但勝在拋跳抑制處理到位。

一鍵泊車、鑰匙遙控泊車、遠程控制(發動機、空調、空氣凈化、遠程防盜追蹤)、后追尾預警、開門碰撞預警、隨動氛圍燈、同級最大天窗、电子擋把、安第斯灰車漆,這些同級罕見甚至前所未見的配置,都被新款CS75一一用上。

(售價:9.98-15.98萬元)

相信這是CS75深思熟慮后的改進,因為長安深知顏值拼不過WEY VV5,內飾氛圍、机械規格也難敵領克01,為此選擇在產品年輕化、科技互聯環節大下苦功,清晰的定位有望搶佔豪華自主SUV的年輕潛在買家。

相近的預算,CS75要說服國人不選合資緊湊型SUV,尚屬馳高鶩遠。我想,大概還差一份如逸動、睿騁CC般驚艷、精緻、創新的設計手稿吧。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

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

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

※回頭車貨運收費標準

Api接口簽名驗證

通過特性來統一驗證的入口,實現ActionFilterAttribute接口來進行接口的簽名驗證

    /// <summary>
    /// 標準接口基類Controller
    /// </summary>
    [SignVerification]
    public abstract class BaseApiController : Controller
    {
    }
    
    /// <summary>
    /// 接口簽名驗證
    /// </summary>
    public class SignVerificationAttribute : ActionFilterAttribute,IAuthenticationFilter
    {
    }

實現的思路為:

1.不同對接方的接口(插件)定義不同的驗證key,不同的插件間不能混用驗證key

2.不同的插件生成不同的partnerId,partnerKey。請求的Url中需要攜帶partnerId,通過partnerId作為key在redis中找到對應的插件驗證信息(包括:partnerId,partnerKey等)

3.Url參數中必須包含partnerId,ts(時間戳),sign(加密簽名)。ts時間戳的有效時間為5分鐘,sign為(時間戳:formBody:partnerId:partnerKey)的MD5加密

4.如果通過partnerId可以找到對應的驗證信息,再把(時間戳:formBody:partnerId:partnerKey)MD5加密后和sign比較確保請求沒有被篡改

5.確保partnerId為當前插件而非其他插件的,因為redis是共用的,只是通過key去取值而已

簽名方式

將時間戳和請求Form參數以及PartnerKey以冒號連接,如(時間戳:body:partnerId:PartnerKey)
將連接好的字符串進行MD5生成sign

Url參數

參數 說明 類型 必須 備註
pid partnerId string  
ts 時間戳(格式:yyyyMMddHHmmss) string 時間戳的有效時間為5分鐘
sign MD5(時間戳:body:partnerId:pkey) string 參考簽名方式

具體代碼實現

    /// <summary>
    /// 接口簽名驗證
    /// </summary>
    public class SignVerificationAttribute : ActionFilterAttribute, IAuthenticationFilter
    {
        private readonly IDefaultUserService _defaultUserService;
        private readonly IInterfaceSignProvider _interfaceSignProvider;
        public SignVerificationAttribute()
        {
            _defaultUserService = ObjectContainer.GetService<IDefaultUserService>();
            _interfaceSignProvider = ObjectContainer.GetService<IInterfaceSignProvider>();
        }

        public void OnAuthentication(AuthenticationContext filterContext)
        {
            var request = filterContext.HttpContext.Request;
            var partnerId = request.QueryString["pid"];
            var timeStamp = request.QueryString["ts"];
            var sign = request.QueryString["sign"];//獲取Url參數
            var body = GetBodyText(request.InputStream);

            if (!ValidSign(filterContext,timeStamp, sign, body,partnerId,out IInterfaceSignInfo signInfo))//加密驗證
            {
                filterContext.Result = new ApiResult {Success = false, ErrorMessage = "無效簽名"};
                return;
            }

            var service = ObjectContainer.GetService<IAuthenticationService>();
            var userId = _defaultUserService.GetDefaultUserId(signInfo.LicNo);
            var identity = service.SignIn(userId, signInfo.LicNo, false, TimeSpan.FromMinutes(5), SessionType.WebApi);
            var newPrincipal = new GenericPrincipal(identity, new string[] { });
            filterContext.Principal = newPrincipal;
        }
        private static string GetBodyText(Stream stream)
        {
            using (var ms = new MemoryStream())
            {
                stream.CopyTo(ms);
                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }

        private bool ValidSign(AuthenticationContext filterContext,string timeStamp, string sign, string body,string partnerId,out IInterfaceSignInfo signInfo)
        {
            signInfo = null;
            if (!string.IsNullOrEmpty(timeStamp) && !string.IsNullOrEmpty(sign)&& !string.IsNullOrEmpty(partnerId))
            {
                var cache = _interfaceSignProvider.GetInterfaceSignInfo(partnerId);//通過partnerId當key讀取redis
                if (cache.Enabled)
                {
                    var areaName = filterContext.RouteData.DataTokens["area"]?.ToString().ToLower();//獲取請求的area,即請求的是哪個插件
                    if (string.IsNullOrEmpty(areaName) || !cache.PluginCode.ToLower().StartsWith(areaName))
                    {
                        return false;//PluginCode需以areaName開頭,否則意味着不是同一個插件(如:PluginCode=juwov1,areaName=JuWo)
                    }
                    if (DateTime.TryParseExact(timeStamp, "yyyyMMddHHmmss", CultureInfo.CurrentCulture.DateTimeFormat, DateTimeStyles.AllowWhiteSpaces, out var time) &&
                        (DateTime.Now - time).TotalMinutes <= 5)//時間戳有效期為5分鐘
                    {
                        signInfo = cache;
                        var hashKey = EncryptHelper.Hash($"{timeStamp}:{body}:{partnerId}:{cache.PartnerKey}", "MD5").ToLowerInvariant();//MD5加密對比
                        return string.Equals(hashKey, sign);
                    }
                }
                
            }
            return false;
        }
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext){}
    }

 

這樣就實現了接口的簽名驗證了。但是還有一個問題是,如果同時存在多個不同的對接接口(插件)時,partnerId,PartnerKey應該是不一樣的。即插件1和插件2的驗證key是不能混用的。

可以通過路由來區分不同的插件,來選擇進入不同的area,通過area來區分不同的插件驗證key。

    public class JuWoAreaRegistration: AreaRegistration
    {
        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "JuWo_default",
                "api/JuWo/{controller}/{action}/{id}",
                new {action = "Index", id = UrlParameter.Optional},
                new[] {"iERP.Its.Web.Areas.JuWo.Controllers"}
            );
        }

        public override string AreaName => "JuWo";
    }

 在之前的ValidSign方法中,通過var areaName = filterContext.RouteData.DataTokens[“area”]?.ToString().ToLower();來獲取到當前請求的是哪個插件,在把url上獲取到的partnerId與我們之前約定好的比較看是否能對應。

 

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

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

厲害了!除了find命令,還有這麼多文件查找命令,高手必備!

大家好,我是良許。

在系統里查找文件,是所有工程師都必備的技能(不管你用的是 Windows 、Linux、還是 MacOS 系統)。對於 Linux 操作系統,單單一個 find 命令就可以完成非常多的搜索工作。

但是,文件搜索命令遠不止一個 find 命令,還有很多。本文就對 Linux 下文件搜索命令進行一個科普,讓你能夠在短時間內找到自己需要的文件。

1. find

find 命令應該是最經典的命令了,談到搜索工具第一個想到的肯定是 find 命令。但是,find 命令非常強大,想要把它的功能都介紹一遍,恐怕要寫好幾篇文章。

所以,這裏就偷個懶,介紹最基本的,根據文件名查找文件的方法。假如我們想搜索當前目錄(及其子目錄)下所有 .sh 文件,可以這樣搜索:

2. locate

locate 是另外一個根據文件名來搜索文件的命令。區別於 find 命令,locate 命令無需指定路徑,直接搜索即可。

這個命令不是直接去系統的各個角落搜索文件,而是在一個叫 mlocate.db 的數據庫下搜索。這個數據庫位於 /var/lib/mlocate/mlocate.db ,它包含了系統里所有文件的索引,並且會在每天早上的時候由 cron 工具自動更新一次。

正因為如此,locate 的搜索速度遠快於 find 命令,因為它直接在數據庫里檢索,速度自然更快。

locate 命令在找到文件之後,將直接显示該文件的絕對路徑,比如:

但是 locate 命令有個弊端,它無法搜索當天所創建的文件,因為它的數據庫一天只在早上更新一次。比如我現在創建一個新文件,locate 沒辦法搜索到:

為了解決這個問題,我們可以使用 updatedb 命令手動去更新它的數據庫:

$ sudo updadb

然後,我們就可以搜索到新文件了。

3. which

which 命令主要用來查找可執行文件的位置,它搜索的位置指定在 $PATH$MANPATH 環境變量下的值,默認情況下,which 命令將显示可執行文件的第一個存儲位置:

如果某個可執行文件存儲在多個位置,可以使用 -a 選項列出所有的位置。

如果你想一次性查找多個文件,可以直接跟在 which 命令後面即可。

4. whereis

whereis 命令會在系統默認安裝目錄(一般是有root權限時默認安裝的軟件)查找二進制文件、源碼、文檔中包含給定查詢關鍵詞的文件。(默認目錄有 /bin, /sbin, /usr/bin, /usr/lib, /usr/local/man等類似路徑)。

一般包含以下三部分內容:

  • 二進制文件的路徑
  • 二進制文件的源碼路徑
  • 對應 man 文件的路徑

比如我們現在搜索 ls 命令:

我們可以使用 -b 選項來只搜索可執行文件所在位置,使用 -B 選項指定搜索位置,使用 -f 選項列出文件的信息。

同樣地,我們可以使用 -s 限定只搜索源碼路徑,使用 -m 搜索 man page 路徑,使用 -s 指定搜索源代碼文件的路徑,使用 -M 指定搜索幫助文件的路徑。

公眾號:良許Linux

有收穫?希望老鐵們來個三連擊,給更多的人看到這篇文章

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

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

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

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

※回頭車貨運收費標準

「虹之松原」原來是海岸保安林 國寶級景點靠公私協力經營

環境資訊中心特約記者 廖靜蕙報導

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

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?