分類
發燒車訊

電動車電池與太陽能成本下降飛快,再生能源主宰的日子不遠了?

  電動車電池的成本下降速度超乎預期,甚至低於國際能源署(IEA)原本預估的 2020 年成本數值,且不少研究也指出,太陽能在 2020 年代將某些地區成為最便宜的能源選項,彭博新聞認為,便宜的電池與太陽能發電兩者相輔相成的結果,將加速再生能源主宰能源市場的趨勢。   國際能源署在 2013 年時,原本預估 2020 年電動車電池價格將會下降至每度電 300 美元,不過,由斯德哥爾摩環境機構最近登上《自然氣候變化(Nature Climate Change)》期刊的研究中指出,全球電動車電池價格已從 2007 年的每千瓦小時 1,000 美元,下降至 2014 年的每千瓦小時 410 美元,平均每年成本下滑 14%,且特斯拉(Tesla)及 Nissan 等電動車製造商領頭羊的價格也年減約 8%,來到 2014 年的每千瓦小時 300美元,提早 6 年達到國際能源署預定目標。   但這所謂的每千瓦小時 300 美元,除了顯示電動車電池成本下降速度超乎預期外,是否還意味著電動車躍起的時代即將來臨呢?全球顧問公司麥肯錫(Mckinsey & Company)在 2011 年曾做了一張圖表,顯示不同的油價與電池價格情況下,純電動車、插電式混合電動車、油電混合車及一般汽車何者較具競爭力,灰色區塊的部分則是 2011 年的價格區間。從下圖圖表中可以看出,當電動車電池價格位於每千瓦小時約 300 美元左右時,就是電動車競爭力逐漸起飛的時刻。    
 

  (Source:)     雖然在過去一年中,油價已下跌至每加侖 2 美元,但若電池價格也跟著不斷下跌,圖表中的灰色矩形就會繼續向左移動。該研究作者認為,若按照特斯拉執行長 Elon Musk 所言,特斯拉正在興建的超級電池工廠真能大舉降低電池組成本 30%,且天然氣價格若反彈回 3 美元區間,將可能使電動車成功在大多數地區取代一般汽車的主宰地位。   此外,根據聯合國環境署(UNEP)於 3 月 31 公布的數據指出,2014 年全球對於再生能源投資額達 2,700 億美元,而新增的再生能源裝置容量,也超過往年的成長數字,來到歷史新高的 103 GW。   即便如此,但 2014 年全球再生能源發電總量僅占 9.1%,較 2013 年的 8.5% 成長 0.6 個百分點,雖然成長速度相當緩慢,且若等到再生能源發電量占全球發電量一半的份額,得等到 2080 年才可望實現。不過,太陽能發電成本下降速度增快,加上不少研究都預估太陽能最快將在 2020 年代就能成為最便宜的能源類型,或許照這樣看來,不用等到 60 年後,就能預見再生能源主宰能源市場的世界了。   便宜的電池與太陽能發電兩者可說是相輔相成,彭博新聞認為,電動車電池價格下跌能將汽車從傳統的汽油切換到電網連結,雖然目前大多數的電網仍然由燃煤發電驅動,但若太陽能發電成本下降速度夠快,搭配如特斯拉等公司欲打造的便宜家用儲能電池組,或許能解決太陽能發電不夠穩定、無法成為基載電力的缺點,以取代燃煤發電在電網中的主導角色。     本文全文授權轉載自《科技新報》─〈〉     (首圖來源:Flickr/CC BY 2.0)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

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

※超省錢租車方案

分類
發燒車訊

作為一個Java開發你用過Jib嗎

1. 前言

JibGoogle開發的可以直接構建 Java應用的DockerOCI鏡像的類庫,以MavenGradle插件形式提供。它最騷操作的是可以在沒有Docker守護程序的情況下構建,也就是說,您不必在計算機上安裝docker守護程序!儘管Spring Boot 2.3.0.RELEASE已經推出了構建鏡像的功能,胖哥還是忍不住要試試Jib

其實最騷的還是名字。

2. Docker構建流程和Jib的構建流程

沒有對比就沒有傷害。我們還是要對比一下這兩者的構建流程。

Docker構建流程需要我們先把項目打成Jar然後編寫Dockerfile,然後使用Docker構建功能進行構建鏡像、運行容器。流程如下:

而Jib是這樣構建的:

作為一個Java開發者,不用再關心各種無關的命令和操作,只需要專註於Java,而且高效穩定以及可復用的增量構建。為什麼Jib能這麼快而高效?

傳統上,將Java應用程序與應用程序Jar一起構建為單個圖像層,而Jib的構建策略將Java應用程序分為多層,以進行更細化的增量構建。更改代碼時,僅重建更改,而不重建整個應用程序。

3. Jib構建Spring Boot應用

接下來我將演示如何將Spring Boot 應用打成鏡像並上傳到Dockerhub倉庫。

Maven工程為例,我們只需要在pom.xml中引入Jib Maven 插件。默認情況下Jib會把我們打好的鏡像上傳到Googlegcr.io倉庫,實際中我們會把打好的鏡像上傳到私有倉庫,所以我們要加一些個性化配置。這裏我以dockerhub倉庫為例添加一些個性化配置:

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>2.4.0</version>
    <configuration>
        <!-- 相當於 Dockerfile 中的 FROM -->
        <from>
            <image>amazoncorretto:8</image>
        </from>
        <to>
            <!--構建鏡像名稱,這裏我使用maven中定義的項目名稱-->
            <image>daxus/${project.name}</image>
            <!--私有倉庫的賬號密碼-->
            <auth>
                <username>felordcn</username>
                <password>yourpassword</password>
            </auth>
            <!--Docker 鏡像的 tag 這裏使用maven定義的版本號-->
            <tags>
                <tag>
                    ${project.version}
                </tag>
            </tags>
        </to>
    </configuration>
</plugin>

然後在項目根目錄執行mvn clean compile jib:build就可以了。

其實也可以簡單引入Jib插件:

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>2.4.0</version>
</plugin>

只不過我們的命令會更複雜一些,需要指定一些必要的參數,例如:

mvn clean compile jib:build \
    -Djib.to.image=myregistry/myimage:latest \
    -Djib.to.auth.username=$USERNAME \
    -Djib.to.auth.password=$PASSWORD

更多的定製命令可參考官方文檔:

https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#extended-usage

4. 總結

Jib使用起來非常簡單,讓開發人員以Java的風格來完成Docker鏡像的構建,能夠大大改善編程的體驗。多多關注:碼農小胖哥 獲取更多有用的編程乾貨教程。

關注公眾號:Felordcn 獲取更多資訊

個人博客:https://felord.cn

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

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

※超省錢租車方案

分類
發燒車訊

Java 反射簡介

本文部分內容參考博客。點擊鏈接可以查看原文。

1. 反射的概念

反射是指在運行時將類的屬性、構造函數和方法等元素動態地映射成一個個對象。通過這些對象我們可以動態地生成對象實例,調用類的方法和更改類的屬性值。

2. 使用場景

什麼情況下運用JAVA反射呢?如果編譯時根本無法預知對象和類可能屬於哪些類,程序只依靠運行時信息來發現該對象和類的真實信息,此時就必須使用反射。

使用反射可以實現下面的功能:

  • 在運行時判斷任意一個對象所屬的類
  • 在運行時構造任意一個類的對象
  • 在運行時判斷任意一個類所具有的方法和屬性
  • 在運行時調用任意一個對象的方法
  • 生成動態代理

3. 獲得Class對象的幾種方式

前面已經介紹過了,每個類被加載之後,系統就會為該類生成一個對應的Class對象,通過該Class對象就可以訪問到JVM中的這個類。在Java程序中獲得Class對象通常有如下3種方式。

  • 使用Class類的forName(String clazzName)靜態方法。該方法需要傳入字符串參數,該字符串參數的值是某個類的全限定類名(必須添加完整包名)。
  • 調用某個類的class屬性來獲取該類對應的Class對象。例如,Person.class將會返回Person類對應的Class對象。
  • 調用某個對象的getClass()方法。該方法是java.lang.Object類中的一個方法,所以所有的Java對象都可以調用該方法,該方法將會返回該對象所屬類對應的Class對象。

對於第一種方式和第二種方式都是直接根據類來取得該類的Class對象,相比之下,第二種方式有如下兩種優勢。

  • 代碼更安全。程序在編譯階段就可以檢查需要訪問的Class對象是否存在。
  • 程序性能更好。因為這種方式無須調用方法,所以性能更好。

也就是說,大部分時候我們都應該使用第二種方式來獲取指定類的Class對象。但如果我們只有一個字符串,例如“java.lang.String”,若需要獲取該字符串對應的Class對象,則只能使用第一種方式,使用Class的forName(String clazzName)方法獲取Class對象時,該方法可能拋出一個ClassNotFoundException異常。一旦獲得了某個類所對應的Class對象之後,程序就可以調用Class對象的方法來獲得該對象和該類的真實信息了。

4. Class類 API介紹

通過class類我們能夠獲取大量的信息:

  1. 獲取構造函數
  • Connstructor getConstructor(Class<?>… parameterTypes):返回此Class對象對應類的指定public構造器。
  • Constructor<?>[] getConstructors():返回此Class對象對應類的所有public構造器。
  • Constructor getDeclaredConstructor(Class<?>… parameterTypes):返回此Class對象對應類的指定構造器,與構造器的訪問權限無關。
  • Constructor<?>[] getDeclaredConstructors():返回此Class對象對應類的所有構造器,與構造器的訪問權限無關。
  1. 獲取方法
  • Method getDeclaredMethod(String name, Class<?>… parameterTypes):返回此Class對象對應類的指定方法,與方法的訪問權限無關。
  • Method[] getDeclaredMethods():返回此Class對象對應類的全部方法,與方法的訪問權限無關。
  1. 獲取屬性
  • Field getField(String name):返回此Class對象對應類的指定public Field。
  • Field[] getFields():返回此Class對象對應類的所有public Field。
  • Field getDeclaredField(String name):返回此Class對象對應類的指定Field,與Field的訪問權限無關。
  • Field[] getDeclaredFields():返回此Class對象對應類的全部Field,與Field的訪問權限無關。
  1. 獲取Class對應類上所包含的Annotation。
  • A getAnnotation(Class annotationClass):試圖獲取該Class對象對應類上指定類型的Annotation;如果該類型的註釋不存在,則返回null。
  • Annotation[] getAnnotations():返回該Class對象對應類上的所有Annotation。
  • Annotation[] getDeclaredAnnotations():返回直接修飾該Class對應類的所有Annotation。
  1. 獲取Class對象對應類包含的內部類。
  • Class<?>[] getDeclaredClasses():返回該Class對象對應類里包含的全部內部類。
    如下方法用於訪問該Class對象對應類所在的外部類。
  • Class<?> getDeclaringClass():返回該Class對象對應類所在的外部類。
    如下方法用於訪問該Class對象對應類所繼承的父類、所實現的接口等。
  • Class<?>[] getInterfaces():返回該Class對象對應類所實現的全部接口。
  1. 獲取Class對象對應類所繼承的父類
  • Class<? super T> getSuperclass():返回該Class對象對應類的超類的Class對象。
  1. 獲取Class對象對應類的修飾符、所在包、類名等基本信息。
  • int getModifiers():返回此類或接口的所有修飾符。修飾符由public、protected、private、final、static、abstract等對應的常量組成,返回的整數應使用Modifier工具類的方法來解碼,才可以獲取真實的修飾符。
  • Package getPackage():獲取此類的包。
  • String getName():以字符串形式返回此Class對象所表示的類的名稱。
  • String getSimpleName():以字符串形式返回此Class對象所表示的類的簡稱。
  1. 判斷該類是否為接口、枚舉、註釋類型等
  • boolean isAnnotation():返回此Class對象是否表示一個註釋類型(由@interface定義)。
  • boolean isAnnotationPresent(Class<? extends Annotation> annotationClass):判斷此Class對象是否使用了Annotation註釋修飾。
  • boolean isAnonymousClass():返回此Class對象是否是一個匿名類。
  • boolean isArray():返回此Class對象是否表示一個數組類。
  • boolean isEnum():返回此Class對象是否表示一個枚舉(由enum關鍵字定義)。
  • boolean isInterface():返回此Class對象是否表示一個接口(使用interface定義)。
  • boolean isInstance(Object obj):判斷obj是否是此Class對象的實例,該方法可以完全代替instanceof操作符。

上面的多個getMethod()方法和getConstructor()方法中,都需要傳入多個類型為Class<?>的參數,用於獲取指定的方法或指定的構造器。關於這個參數的作用,假設某個類內包含如下3個info方法簽名:

  • public void info()
  • public void info(String str)
  • public void info(String str , Integer num)

這3個同名方法屬於重載,它們的方法名相同,但參數列表不同。在Java語言中要確定一個方法光有方法名是不行的,例如,我們指定info方法——實際上可以是上面3個方法中的任意一個!如果需要確定一個方法,則應該由方法名和形參列表來確定,但形參名沒有任何實際意義,所以只能由形參類型來確定。例如,我們想要確定第二個info方法,則必須指定方法名為info,形參列表為String.class——因此在程序中獲取該方法使用如下代碼:

clazz.getMethod("info",String.class);

使用反射生成對象

  1. 利用構造函數生成對象
  • 使用Class對象的newInstance()方法來創建該Class對象對應類的實例,這種方式要求該Class對象的對應類有默認構造器,而執行newInstance()方法時實際上是利用默認構造器來創建該類的實例。
  • 先使用Class對象獲取指定的Constructor對象,再調用Constructor對象的newInstance()方法來創建該Class對象對應類的實例。通過這種方式可以選擇使用指定的構造器來創建實例。
Constructor c = clazz.getConstructor(String.class);
c.newInstance("xx");

調用方法

Method setProName = aClass.getDeclaredMethod("setProName",String.class);
setProName.setAccessible(true);
etProName.invoke(product,"我是一個產品");

操作屬性

Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("fieldName:"+declaredField.getName()+" filedType:"+declaredField.getType());
        }
        Field proName = aClass.getDeclaredField("proName");
        proName.setAccessible(true);
        proName.set(product,"我是一個產品");
        System.out.println("修稿屬性:"+product);

操作數組

//使用反射動態地創建數組
//創建一個元素類型為String,長度為3的數組
Object arr = Array.newInstance(String.class, 3);
//依次為arr數組中index為0,1,2的元素賦值
Array.set(arr, 0, "榮耀盒子");
Array.set(arr, 1, "榮耀8手機");
Array.set(arr, 2, "華為mate9保時捷版");
Object o1= Array.get(arr, 0);
Object o2= Array.get(arr, 1);
Object o3= Array.get(arr, 2);
System.out.println(o1);
System.out.println(o2);
System.out.println(o3);

5. 使用Demo

public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        Class<Product> aClass = Product.class;
        Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor.getName());
        }
        Constructor<Product> constructor = aClass.getConstructor(int.class, String.class);
        Product product = constructor.newInstance(10, "ds");
        System.out.println("創建對象:"+product);

        //獲取方法並調用
        Method setProName = aClass.getDeclaredMethod("setProName", String.class);
        setProName.setAccessible(true);
        setProName.invoke(product,"我是一個產品");
        System.out.println("調用方法:"+product);

        //獲取屬性,並設置屬性的值
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("fieldName:"+declaredField.getName()+" filedType:"+declaredField.getType());
        }
        Field proName = aClass.getDeclaredField("proName");
        proName.setAccessible(true);
        proName.set(product,"我是一個產品");
        System.out.println("修稿屬性:"+product);

        //使用反射動態地創建數組
        //創建一個元素類型為String,長度為3的數組
        Object arr = Array.newInstance(String.class, 3);
        //依次為arr數組中index為0,1,2的元素賦值
        Array.set(arr, 0, "榮耀盒子");
        Array.set(arr, 1, "榮耀8手機");
        Array.set(arr, 2, "華為mate9保時捷版");
        Object o1= Array.get(arr, 0);
        Object o2= Array.get(arr, 1);
        Object o3= Array.get(arr, 2);
        System.out.println(o1);
        System.out.println(o2);
        System.out.println(o3);
        
        System.out.println("end...");
    }
}

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

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

※超省錢租車方案

分類
發燒車訊

法國黃背心運動滿週年 萬人上街抗議

摘錄自2019年11月19日公視報導

11月17號適逢法國黃背心運動一週年,去年不滿總統馬克宏調漲油價的民眾發起抗議行動,在各大城市遍地開花,並逐漸演變成反對馬克宏政府政策的社運。直到現在,仍有部分示威者,每星期六都會固定集會,提醒政府他們怒火難平。今年再度出現幾萬人走上街頭的盛大場面。有群眾和鎮暴警察發生衝突,還有人闖進巴黎的老佛爺百貨,讓業者被迫停業一天。

抗議民眾表示,「我很高興能夠在這向馬克宏宣告:我們就在這裡,我們還在這裡,黃背心運動不死。儘管他們多方試圖摧毀黃背心,但黃背心屹立不搖,我們都是為了法國。」

近幾個月來,黃背心運動趨於和緩,但週年紀念又讓情勢再度激化,數萬人走上街頭。部分抗議人士推翻路邊車輛,點燃垃圾桶等物,還向鎮暴警察扔擲石頭,而警方也以催淚瓦斯和水柱還擊和驅散人群。

根據法國內政部的說法,法國全國各地星期六一共逮捕了264人,其中巴黎就佔了六成以上。黃背心支持者表示,目前他們考慮加入其他工會行動,參與12月5號開始反對馬克宏年金改革的無限期大罷工。

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

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

※超省錢租車方案

分類
發燒車訊

自已做動畫及編寫程序搞清楚最大堆的實現原理

目錄

  • 背景
  • 概念
  • 最大堆
    • 最大堆的線性存儲
    • 動畫實現最大堆加入新元素
    • 代碼實現最大堆加入新元素
    • 動畫實現最大堆取出最大元素
    • 代碼實現最大堆取出最大元素
    • 程序測試
  • 最大堆的應用–優先隊列
  • 寫在最後

背景

  • 二叉樹是數據結構中的重點,也是難點。二叉樹比數組、棧、隊列等線性結構相比複雜度更高,想要做到心中有“樹”,需要自己動手畫圖、觀察、思考,才能領會其真諦。
  • 在上篇文章《自己動手作圖深入理解二叉樹、滿二叉樹及完全二叉樹》中,我們對完全二叉樹有了一定認識,該文將對一種特殊的完全二叉樹”最大堆”進行底層研究。

概念

堆(heap)通常是一個可以被看做一棵二叉樹的數組對象。堆總是滿足下列性質:

  • 堆總是一棵完全二叉樹。
  • 堆中某個節點的值總是不大於或不小於其父節點的值;

最大堆

  • 根節點最大的堆叫做最大堆
最大堆的線性存儲
  • 由於堆是一種特殊的完全二叉樹,可以利用數組集合形成線性存儲的數據結構。
/**
 * 最大堆的底層實現--數組集合形成線性存儲的數據結構
 *  * @author zhuhuix
 * @date 2020-06-28
 */
public class MaxHeap<E extends Comparable<E>> {

    // 存放元素的數組集合
    private ArrayList<E> list;

    MaxHeap() {
        this.list = new ArrayList<>();
    }

    // 得到左孩子索引
    private int getLeftChildIndex(int i) {
        return (2 * i + 1);
    }

    // 得到右孩子索引
    private int getRightChildIndex(int i) {
        return (2 * i + 2);
    }

    // 得到父結點索引
    private int getParentIndex(int i) {
        if (i == 0) {
            throw new IllegalArgumentException("非法索引值");
        } else {
            return ((i - 1) / 2);
        }
    }
}
動畫實現最大堆加入新元素
  • 加入到數組集合尾部的元素與父結點進行比較,通過上浮操作,保證所有子結點不能大於父結點。
代碼實現最大堆加入新元素
/**
 * 最大堆的底層實現
 *
 * @author zhuhuix
 * @date 2020-06-28
 */
public class MaxHeap<E extends Comparable<E>> {

    // 存放元素的數組集合
    private ArrayList<E> list;

    MaxHeap() {
        this.list = new ArrayList<>();
    }

    // 得到左孩子索引
    private int getLeftChildIndex(int i) {
        return (2 * i + 1);
    }

    // 得到右孩子索引
    private int getRightChildIndex(int i) {
        return (2 * i + 2);
    }

    // 得到父結點索引
    private int getParentIndex(int i) {
        if (i == 0) {
            throw new IllegalArgumentException("非法索引值");
        } else {
            return ((i - 1) / 2);
        }
    }

    // 添加元素
    public void add(E e) {
        this.list.add(e);
        /**
         * 將加入的結點與父結點進行比較:
         * 如果加入的結點大於父結點,則進行上浮
         * 直至新結點小於或等於父結點為止
         */

        // 獲取當前添加元素在數組中的索引
        int i = this.list.size() - 1;
        while (i > 0) {
            E current = this.list.get(i);
            E parent = this.list.get(getParentIndex(i));
            // 如果父結點元素大於當前加入的元素,則進行交換
            if (parent.compareTo(current) < 0) {
                // 交換新加入的結點與父結點的位置
                Collections.swap(this.list, i, getParentIndex(i));
            } else {
                break;
            }
            i = getParentIndex(i);
        }
    }
    
}
動畫實現最大堆取出最大元素
  • 獲取最大堆中的根結點,即為最大元素;並把尾部結點放置到根結點,並通過下沉操作,把子結點中的最大元素移動根結點。
代碼實現最大堆取出最大元素
/**
 * 最大堆的底層實現
 *
 * @author zhuhuix
 * @date 2020-06-28
 */
public class MaxHeap<E extends Comparable<E>> {

    // 存放元素的數組集合
    private ArrayList<E> list;

    MaxHeap() {
        this.list = new ArrayList<>();
    }

    // 得到左孩子索引
    private int getLeftChildIndex(int i) {
        return (2 * i + 1);
    }

    // 得到右孩子索引
    private int getRightChildIndex(int i) {
        return (2 * i + 2);
    }

    // 得到父結點索引
    private int getParentIndex(int i) {
        if (i == 0) {
            throw new IllegalArgumentException("非法索引值");
        } else {
            return ((i - 1) / 2);
        }
    }

    // 查找最大元素
    public E findMax() {
        if (this.list.size() == 0) {
            return null;
        }
        // 最大堆中的元素永遠在根結點
        return this.list.get(0);
    }

    // 取出最大元素
    public E getMax() {
        if (findMax() != null) {
            E e = findMax();

            /**
             * 取出最大元素后,需要把堆中第二大的元素放置在根結點:
             * 將根結點元素與最後面的元素進行交換,
             * 讓最後面的元素出現在根結點,並移除最大元素
             * 將根結點的元素與左右孩子結點比較,直至根結點的元素變成最大值
             */
            int i = 0;
            Collections.swap(this.list, i, this.list.size() - 1);
            this.list.remove(this.list.size() - 1);

            // 通過循環進行當前結點與左右孩子結點的大小比較
            while (getLeftChildIndex(i) < this.list.size() && getRightChildIndex(i) < this.list.size()) {
                int leftIndex = getLeftChildIndex(i);
                int rightIndex = getRightChildIndex(i);

                // 通過比較左右孩子的元素哪個較大,確定當前結點與哪個孩子進行交換
                int index = this.list.get(leftIndex).compareTo(this.list.get(rightIndex)) > 0 ? leftIndex : rightIndex;
                if (this.list.get(i).compareTo(this.list.get(index)) < 0) {
                    Collections.swap(this.list, i, index);
                } else {
                    // 如果當前結點都大於左右孩子,則結束比較
                    break;
                }
                i = index;
            }

            return e;
        } else {
            return null;
        }
    }
}

程序測試
/**
 * 最大堆的底層實現--測試程序
 *
 * @author zhuhuix
 * @date 2020-06-28
 */
public class MaxHeapTest {
    public static void main(String[] args) {
        MaxHeap<Integer> maxHeap = new MaxHeap<>();

        // 將10個数字加入形成最大堆
        int[] arrays = {19,29,4,2,27,0,38,15,12,31};
        for (int i = 0; i < arrays.length; i++) {
            maxHeap.add(arrays[i]);
        }

        // 依次從堆中取出最大值
        for (int i = 0; i < arrays.length; i++) {
            System.out.println("第"+(i+1)+"次取出堆目前的最大值:"+maxHeap.getMax());
        }
    }
}

最大堆的應用–優先隊列

優先隊列:出隊的和順序與入隊的順序無關,只與優先級相關;
優先隊列通常可以採用最大堆的數據結構來實現。

/**
 * 用最大堆的數據結構實現優先隊列
 * 
 * @author zhuhuix
 * @date 2020-06-28
 */
public class PriorityQueue<E extends Comparable<E>>  {
    private MaxHeap<E> mhp;
    PriorityQueue() {
        mhp=new MaxHeap<>();
    }

    // 入隊
    public void enqueue(E e) {
        mhp.add(e);
    }

    // 優選級最高的元素出隊
    public E dequeue() {
        return mhp.getMax();
    }

    // 查看優先級最高的元素
    public E getFront() {
        return mhp.findMax();
    }
}

寫在最後

  • 以上通過畫圖、動畫演示、代碼編寫對堆與最大堆的概念和底層實現方式,都作了深入分析;作為最大堆的反向結構,最小堆的實現也是一樣,讀者可參考以上動畫和代碼,動手練習。
  • 畫圖、編碼不易,請點贊、收藏、關注三連!!!

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

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

※超省錢租車方案

分類
發燒車訊

馬來西亞最後一頭蘇門答臘犀牛病逝 全球剩80頭

摘錄自2019年11月24日中央通訊社馬來西亞報導

馬來西亞最後一隻蘇門答臘犀牛,25歲的母犀牛伊曼自2014年被捕獲後,一直在野生動物保護區接受妥善照顧,牠今天(24日)因癌病逝於婆羅洲(Borneo)沙巴(Sabah)。沙巴野生動物部門(Sabah Wildlife Department)主任奧古斯丁(Augustine Tuuga)說:「伊曼的死亡比預期要快,但我們知道,牠已經開始承受極大痛苦。」

蘇門答臘犀牛是體型最小的犀牛,曾廣布亞洲各地,野生蘇門答臘犀牛如今已近乎絕種,據保育人士估計,目前全球僅剩約30至80頭,大多棲息在蘇門答臘和印尼所管轄的婆羅洲地區。馬來西亞2015年宣布野生蘇門答臘犀牛絕種,最後一頭公蘇門答臘犀牛今年5月離世。

保育團體國際犀牛基金會(International Rhino Foundation)說,棲地減少和盜獵導致蘇門答臘犀牛生存於孤立區域,代表牠們繁衍困難,數十年內可能就會滅絕。

自2011年以來,馬來西亞不斷嘗試以體外受精方式,繁殖人工飼養的蘇門答臘犀牛,但迄今尚未成功。

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

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

分類
發燒車訊

詳解電動汽車無線充電技術

Q1:無線充電有哪些方式?原理是什麼?  

  A:現在劃分的無線充電類型有好些種,比如感應式、共振式、微波傳輸式等等,不過總體來說,它們的基本原理都是一樣的,就是利用交變電磁場的電磁感應,來實現能量的無線傳輸。    感應式的無線電能傳輸算是目前比較成熟的技術,很多手機無線充電、甚至我們常見的電磁爐就是利用的這種原理。由於數碼設備空間小,接收線圈也小,加上充電設備功率小,所以通常充電的距離近(甚至需要與充電座接觸),不過相對電磁輻射也小。    共振式則是麻省理工目前在開發的一類充電技術,說起來也不複雜,他們利用電磁感應現象,加上共振的原理,能提升無線充電的效率。共振傳輸的距離比普通感應式更遠一些,而麻省理工目前正在進行小型化的研究——對於車長好幾米的電動車來說,這方面的技術壓力倒不是太大。    微波傳輸式此前更多出現在科幻電影或者小說裡面,實際上它也是無線電力傳輸的一個很好的方式,只不過受到發送功率等方面的限制,並未大規模實用化。微波傳輸的最大好處就是傳輸距離遠,甚至可以實現航天器與地面之間的能量傳輸,同時還可以實現定向傳輸(發射天線有方向性),未來前景值得期待。  

 

Q2:無線充電的好處有哪些?

  A:無線充電的第一個好處就是不需要線,不必為了到處找充電線而費神。第二就是無線充電在硬體方面的標準更容易統一。  
Q3:有待解決的問題有哪些?   A: 一、傳輸效率是所有無線充電都面臨的問題,對於電動車這樣充電功率更大的“電器”來說更是如此——電能首先轉換為無線電波,再由無線電波轉換成電能,這兩次轉換都會損失不少的能量。   二、電磁相容也是無線充電需要解決的技術瓶頸之一。電磁波很容易產生洩漏,當大功率的車用無線充電設備運行時,也會對周圍的生物和電子設備產生影響,甚至會危害人體健康。利用封閉的自動智慧化車庫安裝無線充電設備是解決電磁相容比較好的途徑,不過成本也確實不菲。   三、電氣標準等方面的問題。  
Q4:有哪些典型案例呢?   A:從國外車企來看,特斯拉、沃爾沃、奧迪、寶馬、賓士等傳統汽車都已經開始研發或測試旗下電動車的無線充電系統。全球通訊以及IT界的新貴們也將“觸角”伸向了電動車無線充電的新領域。而在無線充電的規劃和靜態還是動態充電的選擇上,國內外車企則各有不同。  
一、沃爾沃:利用道路進行無線充電  

  在瑞典,沃爾沃集團、瑞典電力公司 Alstom、瑞典能源局正在共同合作測試利用公路給電動汽車充電,通過將兩個電源線鋪設在公路上,電動車經過時便可獲得電力供應。這項技術的核心在於汽車得搭載集電器,集電器與公路上的電纜連線,利用直流電充電。汽車不必走在電纜的中央,但必須時速大於 60 公里。    沃爾沃已在瑞典的 H llered 測試中心建立了一條 1/4 英里長的軌道,用一輛卡車進行測試。未來,當電動汽車需要充電時,必須安裝無線發射器讓道路感知,然後經過加密信號啟動充電功能。由於對速度有要求,沃爾沃的這一充電系統適合在高速路上實行,如果未來成真,人們出遠門的時候就不用擔心電力問題。   利用公路地表進行無線充電很可能是未來的發展方向,相比地面上的設施,它的好處是不需要佔用地面空間,可減少建設、維護成本。汽車不需要停下來進行充電,可持續駕駛。   沃爾沃的這一舉措是為了給電動汽車打造一個良好的充電網路。不過它需要面對很多普及的問題,比如公路建設、設計問題、集電器、電動汽車的支持等。就像無人駕駛一樣,這是一個浩大的工程,短期內還難以實現。  
二、高通:Halo的感應充電系統  

  在2015年4月22日的Formula E電動方程式錦標賽上,高通就展示了自己研發的Halo無線汽車充電技術。只要將車開到充電墊的正上方,當充電線圈對齊之後,電流便會開始輸送到汽車當中。如果汽車和墊子之間存在外來物體,系統還可自動暫停充電。   高通Halo的感應充電系統是個相對直接明瞭的構想:一個由兩個鐵氧體組成的變壓器,兩者的旁邊還各有一個電線線圈。一般來講,這兩個部分是連接在一起的。交流電會在第一個線圈中被轉換成磁場,隨後再被第二個線圈轉換成直流電。而高通Halo卻將兩個鐵氧體分離開來,並讓系統跨越空氣間隔實現最大功率傳輸。    Halo的無線充電器被放置在了車尾的位置,是一個比機上盒稍大一些的金屬盒子,並連接著幾條橙色的電線。至於另一半的充電器,就在汽車的下方。感應充電其實是可以作用於移動中的車輛的。Halo目前已經具備了半動態充電的能力,可在最高30mph的速度下進行電能傳輸。  
三、日產無線充電汽車   日產魔方電動車採用了可在供電線圈和受電線圈之間提供電力的電磁感應方式。即將一個受電線圈裝置安裝在汽車的底盤上,將另一個供電線圈裝置安裝在地面,當電動汽車駛到供電線圈裝置上,受電線圈即可接受到供電線圈的電流,從而對電池進行充電。目前,這套裝置的額定輸出功率為 10kW,一般的電動汽車可在7-8小時內完成充電。    日本無線充電式混合動力巴士:電磁感應式,供電線圈是埋入充電台的混凝土中的。車開上充電台後,當車載線圈對準供電線圈後(重合),車內的儀錶板上有一個指示燈會亮,司機按一下充電按鈕,就開始充電。   
三、中興:無線供電系統   中興通訊的無線供電系統是通過非接觸的電磁感應方式進行電力傳輸。當充電車輛在充電停車位停泊後,就能自動通過無線接入充電場的通信網路,建立起地面系統和車載系統的通信鏈路,並完成車輛鑒權和其他相關資訊交換。   充電位元也可以通過有線或者無線的方式和雲服務中心進行互聯。一旦出現充電和受電的任何隱患,地面充電模組將立即停止充電並報警,確保充電過程安全可靠。最重要的是,無線充電系統在車輛運行時完全不工作,即使車輛在上面駛過,或者在雷雨等惡劣天氣情況下,也能確保安全。  
四、比亞迪:WAVE無線充電墊   比亞迪早在2005年12月就申請了非接觸感應式充電器專利。在2014年7月賣給猶他大學一輛40英尺的純電動巴士,這款巴士就裝配著最新的WAVE無線充電墊。  
五、奧迪:可升降的無線充電系統   奧迪的可升降的無線充電系統最大的特點就是可讓供電線圈更靠近車輛底部的受電線圈,實現了超過90%的電力傳輸效率。這種方式能讓一些高底盤的SUV在充電時保證更好的充電效率。奧迪的無線充電技術僅需要使用者將停車位元元上安置一塊配置線圈和逆變器(AC/AC)充電板,並連接至電網,當車輛停在電板上時,充電過程會自動開啟。   這種充電的原理是充電板內的交變磁場將3.3千瓦的交變電流感應至集成在車內次級線圈的空氣層中,實現電網電流逆向並輸入到車輛的充電系統中。當電池組充滿電時,充電將自動中止。感應式無線充電所需的充電時間與電纜充電所需的充電時間大致相同,且用戶可以隨時中斷充電並使用車輛。   奧迪的無線充電技術效率超過90%,不受譬如雨雪或結冰等天氣因素的影響。同時,交變磁場只有當車輛在充電板上方時才會產生,且不對人體或動物構成傷害。未來利用感應線圈的充電原理,奧迪電動汽車不僅可以在駛入車位後自動開始充電,甚至可以在設有感應線圈的公路上,一邊行駛一邊充電。  
六、特斯拉   在19世紀90年代,尼古拉•特斯拉發明瞭“特斯拉線圈”,能夠通過空氣傳播電力,開啟了無線式電力傳播的時代。在“2011年國際消費電子展”上,美國安利公司旗下子公司富爾頓創新公司展示了無線充電技術,並推出了世界上第一輛無線充電的特斯拉汽車。目前,特斯拉希望能在各個大城市中建立起一張張相互連接的充電網,以解決電動車很容易出現的電力不足問題。   (圖片來源:EEPW)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

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

分類
發燒車訊

前端進階筆記之核心基礎知識—那些HTML標籤你熟悉嗎?

目錄

  • 1、交互實現
    • 1.1 meta標籤:自動刷新/跳轉
    • 1.2 title標籤:消息提醒
  • 2、性能優化
    • 2.1 script標籤:調整加載順序提升渲染速度
    • 2.2 link標籤:通過預處理提升渲染速度
  • 3、搜索優化
    • 3.1 meta標籤:提取關鍵信息
    • 3.2 link標籤:減少重複
    • 3.3 延伸內容:OGP(開放圖表協議)
  • 總結

提到HTML標籤,我們會非常熟悉,開發中經常使用。但我們往往關注更多的是頁面渲染效果及交互邏輯,也就是對用戶可見可操作的部分,比如表單、菜單欄、列表、圖文等。其實還有一些非常重要卻容易忽視的標籤,這些標籤大多數用在頁面頭部head標籤內,雖然對用戶不可見,但如果在某些場景下,比如交互實現、性能優化、搜索優化,合理利用它們可以讓我們在開發中達到事半功倍的效果。

1、交互實現

在實現一個功能的時候,我們編寫的代碼越多,不僅開發成本越高,而且代碼的健壯性也越差。因此我們在開發中提倡編碼簡約原則:Less code, less bug

1.1 meta標籤:自動刷新/跳轉

meta標籤妙用場景一:假如每隔一分鐘就需要刷新頁面,這個時候就可以用到meta標籤:

<meta http-equiv="Refresh" content="60">

meta標籤妙用場景二:假如想讓某個頁面在對用戶展示一段時間后,然後跳轉到其他頁面去,也可用到meta標籤:

<meta http-equiv="Refresh" content="5; URL=page2.html">

上面這行代碼的意思是當前頁面展示5s之後,跳轉到page2.html頁面去。

1.2 title標籤:消息提醒

B/S架構有很多優點,比如版本更新方便、跨平台、跨終端,但在處理某些場景時,比如即時通信時,會變得有點麻煩。

因為前後端通信深度依賴HTTP協議,而HTTP協議採用“請求-響應”模式,這就決定了服務端也只能被動地發送數據。一種低效的解決方案是客戶端通過輪詢機制獲取最新消息(HTML5下可使用WebSocket協議)。

另外在HTML5標準發布之前,瀏覽器沒有開放圖標閃爍、彈出系統消息之類的接口,因此消息提醒功能實現比較困難。但是我們可以通過修改title標籤來達到類似的效果(HTML5下可使用Web Notifications API彈出系統消息)。

下面這段代碼,通過定時修改title標籤內容,模擬了類似消息提醒的閃爍效果:

let msgNum = 1 // 消息條數
let cnt = 0 // 計數器
const inerval = setInterval(() => {
  cnt = (cnt + 1) % 2
  if(msgNum===0) {
    // 通過DOM修改title
    document.title += `聊天頁面`
    clearInterval(interval)
    return
  }
  const prefix = cnt % 2 ? `新消息(${msgNum})` : ''
  document.title = `${prefix}聊天頁面`
}, 1000)

實現效果如下圖所示,可以看到title標籤名稱上有提示文字在閃爍。

通過模擬消息閃爍,可以讓用戶在瀏覽其他頁面的時候,及時得知服務端返回的消息。

通過定時修改title標籤內容,除了用來實現閃爍效果之外,還可以製作其他動畫效果,比如文字滾動,但需要注意瀏覽器會對title標籤文本進行去空格操作;還可以將一些關鍵信息显示到標籤上(比如下載時的進度、當前操作步驟),從而提升用戶體驗。

2、性能優化

性能優化是前端開發中避不開的問題,性能問題無外乎兩方面原因:渲染速度慢請求時間長。性能優化雖然涉及很多複雜的原因和解決方案,但其實只要通過合理地使用標籤,就可以在一定程度上提升渲染速度,以及減少請求時間。

2.1 script標籤:調整加載順序提升渲染速度

由於瀏覽器的底層運行機制,一般情況下,渲染引擎在解析HTML時從上往下執行,若遇到script標籤引用文件,則會暫停解析過程,同時通知網絡線程加載引用文件。
文件加載完成后,再切換至JavaScript引擎來執行對應代碼,代碼執行完成之後,再切換至渲染引擎繼續渲染頁面。
即默認情況下,加載HTML的過程主要有四個步驟:

  • 從上往下解析HTML;
  • 碰到script標籤引用文件,暫停解析,同時通知網絡線程加載引用文件;
  • 文件加載完成,切換至JavaScript引擎來執行對應代碼;
  • 代碼執行完成后,再切換至渲染頁面,繼續渲染HTML。

從這一過程可以看出,頁面渲染過程包含了請求文件以及執行文件的時間,但頁面的首次渲染可能並不依賴這些文件。這些請求和執行文件的動作反而延長了用戶看到頁面的時間,從而降低了用戶體驗。

為了減少這些時間損耗,可以藉助script標籤的三個屬性來實現:

  • async屬性:立即請求文件,但不阻塞渲染引擎,而是文件加載完成后,再阻塞渲染引擎並立即執行文件內容。
  • defer屬性:立即請求文件,但不阻塞渲染引擎,等到解析完HTML之後再執行文件內容。
  • HTML5標準type屬性,對應值為“module”:讓瀏覽器按照ECMA Script6標準將文件當作模塊進行解析,默認阻塞效果同defer,也可以配合async在請求完成后立即執行。

通過對比,我們看出,設置defer和type=”module”最推薦,都是在HTML渲染完成后才執行script引用的文件代碼。
效果圖比較見下面:

另外注意,當渲染引擎解析HTML遇到script標籤引入文件時,會立即進行一次渲染。

所以這也就是為什麼構建工具會把編譯好的引用JavaScript代碼的script標籤放入到body標籤底部。因為當渲染引擎執行到body底部時,會先將已解析的內容渲染出來,然後再去請求相應的JavaScript文件。

如果是內聯腳本(即不通過src屬性引用外部腳本文件直接在HTML中編寫JavaScript代碼的形式),渲染引擎則不會渲染,先執行腳本代碼再渲染頁面。

我們可以來做個試驗驗證下,第一個測試:在HTML頁面中間引用外部js文件

<!DOCTYPE html>
<html lang="en">
    <head><meta charset="UTF-8"><title>引用js腳本</title></head>
    <body>
        <br/><br/><br/><br/><br/>
        <h3>古人學問無遺力,少壯工夫老始成;</h3>
        <script type="text/javascript" src="./test.js"></script>
        <h3>紙上得來終覺淺,絕知此事要躬行。</h3>
    </body>
</html>

引用外部js腳本test.js:alert('男兒何不帶吳鈎,收取關山五十州');
效果圖:

第二個測試:在HTML頁面中間內聯js腳本

<!DOCTYPE html>
<html lang="en">
    <head><meta charset="UTF-8"><title>內聯js腳本</title></head>
    <body>
        <br/><br/><br/><br/><br/>
        <h3>古人學問無遺力,少壯工夫老始成;</h3>
        <script type="text/javascript">
            alert('男兒何不帶吳鈎,收取關山五十州');
        </script>
        <h3>紙上得來終覺淺,絕知此事要躬行。</h3>
    </body>
</html>

效果圖:

2.2 link標籤:通過預處理提升渲染速度

在大型單頁應用進行性能優化時,也許會用到按需賴加載的方式來加載對應的模塊。但是如果能合理利用link標籤的rel屬性值來進行預加載,就能進一步提升渲染速度。

  • dns-prefetch:當link標籤的rel屬性值為“dns-prefetch”時,瀏覽器會對某個域名預先進行dsn解析並緩存。這樣,當瀏覽器在請求同域名資源的時候,能省去從域名查詢IP的過程,從而減少時間損耗。下圖是淘寶網設置的dns預解析。
  • preconnect:讓瀏覽器在一個HTTP請求正式發給服務器前預先執行一些操作,這包括dns解析、TLS協商、TCP握手,通過消除往返延遲來為用戶節省時間。
  • prefetch/preload:兩個值都是讓瀏覽器預先下載並緩存某個資源,但不同的是,prefetch可能會在瀏覽器忙時被忽略,而preload則是一定會被預先下載。
  • prerender:瀏覽器不僅會加載資源,還會解析執行頁面,進行預渲染。

這幾個屬性值恰好反映了瀏覽器獲取文件的過程,它們獲取文件的流程:

  1. 設置dns-prefetch, 然後判斷是否有對dns進行預解析。沒有則進行dns解析,有則執行下一步preconnect;
  2. 執行preconnect, 對ddns、TLS、TCP進行預連接,然後判斷是否已經TCP連接。沒有則進行TCP連接,有則執行下一步prefetch/preload;
  3. 執行prefetch/preload,加載資源文件。然後判斷資源文件是否已經預加載。沒有則進行http進行資源請求下載,有則進行下一步prerender;
  4. 執行prerender, 預渲染頁面。然後判斷預渲染是否成功。沒有預渲染成功則進行渲染,預渲染成功則呈現給用戶看。

流程圖如下:

3、搜索優化

我們寫的前端代碼,除了要讓瀏覽器更好的執行,有時候也要考慮更方便其他程序(如搜索引擎)理解。合理地使用meta標籤和link標籤,恰好能讓搜索引擎更好的理解和收錄我們的頁面。

3.1 meta標籤:提取關鍵信息

通過meta標籤可以設置頁面的描述信息,從而讓搜索引擎更好的展示搜索結果。
比如在百度中搜索“拉勾”,就會發現網站的描述,這些描述信息就是通過meta標籤專門為搜索引擎設置的,目的是方便用戶預覽搜索到的結果。
為了讓搜索引擎更好的識別頁面,除了描述信息之外還可以使用關鍵字,這樣即使頁面其他地方沒有包含搜索內容,也可以被搜索到(當然搜索引擎有自己的權重和算法,如果濫用關鍵字是會被降權的,比如Google引擎會對堆砌大量相同關鍵詞的網頁進行懲罰,降低它被搜索的權重)。

當我們搜索關鍵字“垂直互聯網招聘”的時候搜索結果會显示拉勾網的信息,雖然显示的搜索內容上並沒有看到“垂直互聯網招聘”字樣,實際上因為拉勾網頁面中設置了這個關鍵字。
對應代碼如下:

<meta content="拉勾,拉勾網,拉勾招聘,拉鈎, 拉鈎網 ,互聯網招聘,拉勾互聯網招聘, 移動互聯網招聘, 垂直互聯網招聘, 微信招聘, 微博招聘, 拉勾官網, 拉勾百科,跳槽, 高薪職位, 互聯網圈子, IT招聘, 職場招聘, 獵頭招聘,O2O招聘, LBS招聘, 社交招聘, 校園招聘, 校招,社會招聘,社招" name="keywords">

3.2 link標籤:減少重複

有時候為了用戶訪問方便或者出於歷史原因,對於同一個頁面會有多個網址,又或者在某些重定向頁面,比如:https://xx.com/a.html、 https://xx.com/detail?id=abcd,那麼在這些頁面中可以設置:<link href="https://xx.com/a.html" rel="canonical">這樣可以讓搜索引擎避免花費時間抓取重複網頁。不過需要注意的是,它還有個限制條件,那就是指向的網站不允許跨域。
當然,要合併網址還有其他的方式,比如使用站點地圖,或者在http請求響應頭部添加rel=”canonical”。

3.3 延伸內容:OGP(開放圖表協議)

前面說的是HTML5標準的一些標籤和屬性,下面再延伸說一說基於meta標籤擴展屬性值實現的第三方協議—OGP(open graph protocal, 開放圖表協議)。

OGP是Facebook公司在2010年提出的,目的是通過增加文檔信息來提升社交網頁在被分享時的預覽效果。你只需要在一些分享頁面中添加一些meta標籤及屬性,支持OGP協議的社交網站就會在解析頁面時生成豐富的預覽信息,比如站點名稱、網頁作者、預覽圖片。具體預覽效果會因各個網站而有所變化。

下面是微信文章支持OGP協議的代碼,可以看到通過meta標籤屬性值聲明了:標題、網址、預覽圖片、描述信息、站點名稱、網頁類型和作者信息。

總結

本篇從交互實現、性能優化、搜索優化場景觸發,分別講解了meta標籤、title標籤、link標籤,一級script標籤在這些場景中的重要作用,希望這些內容你都能應用到工作場景中,不再只是了解,而是能夠熟練運用。
最後在思考一下:你還知道哪些“看不見”的標籤及用法?

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

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

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

分類
發燒車訊

湖北宜昌:對無接觸配送商品開展“千單抽查”

  中國消費者報武漢訊田力 記者吳采平)疫情當前,“線上下單+無接觸配送”的方式為消費者解決了“採購難”,“線上買的食材質量會不會不好”等問題。近日,湖北省宜昌市市場監管局對無接觸配送商品進行了“千單抽查”,不打招呼、不發通知、直奔現場。

  近日,湖北省宜昌市伍家崗區市場監管局執法人員譚玄仙來到北山超市九安城店,對待送區的100餘單已打包商品進行了隨機抽查。結果显示,每筆訂單配有“消費明白卡”,且打包袋內的每種商品計量準確、質量合格、價格在合理範圍。

  根據宜昌市新冠肺炎疫情防控指揮部安排,宜昌市市場監管局於日前啟動無接觸配送商品“千單抽查”行動,要求執法人員於次日內對宜昌市參与保障供應的農貿市場、超市和藥店的配送商品進行監督抽查。各地市場監管部門迅速成立檢查組,採取不打招呼、不發通知、直奔現場的方式,開展隨機抽查,重點查看各經營單位是否存在亂漲價、短斤少兩、假冒偽劣和強買強賣等違法行為。

  檢查內容包括有無亂漲價情況。查看檢查當日商品銷售價與進貨價之間的差率是否超過1月19日售價差率標準;有無短斤少兩情況。執法人員攜帶稱重衡器,進行凈含量現場檢測;有無假冒偽劣情況。執法人員通過檢查商品的感官質量、標籤標識,查看是否“山寨”食品或“三無”食品,是否臨近或超過保質期;有無強買強賣情況。是否存在套餐搭配不合理,或者強行配售其他無關商品。

  抽查結果显示,截至當日下午4時,宜昌市市場監管系統共監督抽查無接觸配送商品1114單,其中食品類993單、藥品類121單。發現亂漲價行為3起,未發現短斤少兩、假冒偽劣和強買強賣等違法行為。目前,執法人員已責令相關經營單位立即整改,並將對其整改情況進行回頭看。

  宜昌市市場監管局提醒廣大消費者,若有發現違法行為,應撥打“12315”熱線舉報投訴。圖為執法人員對配送商品進行復秤抽查

責任編輯:邊靜

本站聲明:網站內容來源再生能源資訊網http://www.ccn.com.cn/,如有侵權請聯繫我們,我們將及時處理

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

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

分類
發燒車訊

特斯拉要求員工 4/29 復工,加州工廠可能提前恢復生產

特斯拉已通知部分員工,要求 4 月 29 日重返工作崗位,雖然加州超級工廠所在地的公共衛生部門還沒有公告解除和放鬆居家隔離。特斯拉要求員工提前復工是為了 5 月 3 日前準備好恢復生產。

特斯拉加州超級工廠所在地 Fremont 的公共衛生部門仍然沒有解除居家隔離,超級工廠屬於非必要生產製造工廠,僅可維持最基本營運,生產線處於停產狀態。特斯拉計劃在 5 月 4 日恢復生產,但在正式復工前主管已通知部分員工,要求 4 月 29 日到工廠報到,主要是沖壓、油漆業務員工。特斯拉沒有透露提前復工的員工數量。

Fremont 所屬 Alameda 郡新聞發言人 Ray Kelly 表示,目前居家隔離沒有任何調整,預期 5 月 3 日前公共衛生部門會說明,可能延長、放鬆或完全解除。

特斯拉加州工廠在 3 月 19 日接到政府部門通知,必須停止生產,特斯拉沒有第一時間配合政府部門調整生產線,繼續生產了 5 天,法務團隊也持續與政府部門溝通,特斯拉認為電動車生產屬於必要業務,不能因居家隔離停產,同時為員工提供必要的健康保障措施。停產前特斯拉會測量進入工廠的員工體溫,並向部分員工發放口罩。

政府部門強制要求停工後,特斯拉通知所有員工,除必要工作外,所有員工在家上班,部分無法在家工作的員工列為休假,降低員工薪水,並停止與外部承包商臨時性員工合作。

儘管員工對復工非常期待,但工廠環境和作業方式將使降低傳染變得困難。截至 4 月 26 日,Alameda 郡共報告 1,468 例武漢肺炎病例,52 例死亡,特斯拉工廠大部分員工都住在這區。

選擇在 4 月 29 日部分員工提前復工,對特斯拉意義不僅是工廠恢復營運,也是 4 月 29 日發表第一季財報的日子,投資者會很樂見工廠恢復生產。加州超級工廠生產 Model Y、Model 3、Model X、Model S 電動車,據 Credit Suisse 的分析師估計,關閉後特斯拉每週至少虧損 3 億美元。

關於汽車製造公司何時恢復營運、保障員工安全仍有許多爭議,豐田、Volkswagen、Hyundai 等汽車廠商都計劃 5 月初恢復生產,但汽車工人聯合會代表認為,過早恢復生產對員工非常危險。

(合作媒體:。首圖來源:)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

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