預防全球災難 末日種子庫收6萬新種子樣本

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

挪威北極圈內的「末日種子庫」今(25日)預計將收到來自世界各地的6萬個種子樣本。這個全球最大農作物儲藏庫為了保護作物免於全球性災難,而囤積各類種子。

這些種子將寄存在挪威斯瓦巴群島(Svalbard)內斯匹次柏根島(Spitsbergen Island)朗葉比(Longyearbyen)附近的深山中,距離北極點(North Pole)約1000公里。

法新社報導,掌管種子庫的作物信託基金(Crop Trust)執行長施密茲(Stefan Schmitz)說:「隨著氣候變遷和生物多樣性喪失的速度增加,針對瀕臨滅絕作物的拯救工作產生新的急迫性。」

最新運送的一批將讓種子庫藏提升至約105萬種,這些種子放置在種子庫的三座地窖,這個種子庫被譽為糧食作物的「諾亞方舟」。

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

【其他文章推薦】

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※帶您來看台北網站建置台北網頁設計,各種案例分享

小三通物流營運型態?

※快速運回,大陸空運推薦?

日311地震重災區 女川核電廠2號機通過重啟審查

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

日本女川核電廠2號機以重啟運轉為前提的申請,已通過日本原子力規制委員會審查,成為位於311大地震重災區首座合格的核電廠,也是第2座遭受海嘯侵襲重生的核電廠。

日本放送協會(NHK)報導,東北電力公司希望位於宮城縣的女川核電廠2號機能重啟運轉提出申請,日本原子力規制委員會今(26日)已正式彙整完成表示合格的審查書。

女川核電廠2號機是位於2011年311大地震後遭受重創的東北地方,首度獲審查合格的核電廠機組。東北電力公司在311大地震2年後的2013年,以重啟運轉為前提向原子力規制委員會提出審查申請。

持續進行審議的原子力規制委員會,2019年11月彙整出表示事實上符合新規範標準的審查書草案,並向一般民眾徵集意見。

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

【其他文章推薦】

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

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

HNU_團隊項目_數據庫框架Mybatis_環境配置和樣例,IDEA項目搭建四——使用Mybatis實現Dao層

前言

數據庫從最傳統的JDBC連接方式和數據庫池化技術Hibernate的使用,再到Mybatis的快捷輕量級操作,技術迭代的速度飛快。

在了解了基礎的理論和方法后,學習前沿編程框架、工具,我認為是一種必然的趨勢。

再不看看外面,可能真的要落伍了~

之後,我借團隊項目開發的機會,學習了Mybatis框架,和大家分享一下經驗,願意和大家共同進步!

 

正文

從零開始

參考: 

1. 下載Mybatis的,並且導入

  點擊連接,選擇下載Mybatis的jar包。這裡有三個文件,基礎使用的話,下載第一個mybatis-3.5.3.zip即可,如果需要查看源碼的話,建議將Source code也下載下來,Windows使用zip,Ubuntu使用tar.gz;

  Eclipse導入只要build puth即可,IDEA的話,在File->Project Structure里導入jar;(建議在項目內建一個lib文件夾,便於遷移)

  只是數據庫部分的話,以下兩個包便足夠了。

 

 

2. 新建Java Web Application,編寫數據庫配置文件

文件名可以自定義,我設置的是Mybatis.xml。但是要放到src的根目錄下,這一點要注意。

注意

url的配置信息中 ” & ” 符號無法解析,需要變為 “ & “;

映射文件路徑以 “ / ”作為文件夾,從src作為根目錄進行訪問;

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <!--上面一段是非常重要的,有了這一段,xml的配置就擁有了自動補全,這也是考量Mybatis包是否導入成功的一個方面;-->
 6 <configuration>
 7 <!--    可以兼容多種數據庫,配置多個environment,default為當前配置-->
 8     <environments default="mysql">
 9         <environment id="mysql">
10             <transactionManager type="JDBC"/>
11 <!--            使用數據庫池化技術,詳細可以看官方文檔-->
12             <dataSource type="POOLED">
13                 <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
14                 <property name="url" value="jdbc:mysql://localhost:3306/databaseName?useUnicode=true&amp;serverTimezone=GMT%2B8&amp;characterEncoding=utf-8"/>
15                 <property name="username" value=username"/>
16                 <property name="password" value="password"/>
17             </dataSource>
18         </environment>
19     </environments>
20 <!--    映射文件路徑,需要告訴數據庫,要執行哪些操作,以及數據庫實體類和字段的對應關係,接下來進行解釋-->
21     <mappers>
22         <mapper resource="main/mapper/UserMapper.xml"/>
23     </mappers>
24 </configuration>

 

3. 編寫執行SQL語句的SqlSessionFactory

  可以編寫工具類或者工廠類,避免代碼重複。我這裏設置的是DBTools.java

 1 package main.dao;
 2 
 3 import org.apache.ibatis.io.Resources;
 4 import org.apache.ibatis.session.SqlSession;
 5 import org.apache.ibatis.session.SqlSessionFactory;
 6 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 7 
 8 import javax.annotation.Resource;
 9 import java.io.IOException;
10 import java.io.InputStream;
11 
12 /*
13 Comet_Fei
14 2019/11/17
15 */
16 public class DBTools
17 {
18     private static SqlSessionFactory sqlSessionFactory;
19 
20     static
21     {
22         try
23         {
24             //輸入流讀取文件 Resources Mybatis的自帶加載類
25             InputStream config = Resources.getResourceAsStream("mybatis.xml");
26             //工廠設計模式
27             sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
28         }
29         catch (IOException e)
30         {
31             e.printStackTrace();
32         }
33     }
34 
35     //創建可以執行映射文件sql的sqlsession
36     public static SqlSession getSqlSession()
37     {
38         return sqlSessionFactory.openSession();
39     }
40 }

 

4. 編寫表對應的實體類User.java

 此處可用IDEA的pojo快捷操作,生成對應實體;

package main.pojo;


public class User {

    private String userPhoneNumber;private String userName;private String userPassword;public User(String userPhoneNumber, String userName, String userPassword) {
        this.userPhoneNumber = userPhoneNumber;
        this.userName = userName;
        this.userPassword = userPassword;
    }

    public String getUserPhoneNumber() {
        return userPhoneNumber;
    }

    public void setUserPhoneNumber(String userPhoneNumber) {
        this.userPhoneNumber = userPhoneNumber;
    }public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    @Override
    public String toString() {
        return "User{" +
                "userPhoneNumber='" + userPhoneNumber + '\'' +
                ", userName='" + userName + '\'' +
                ", userPassword='" + userPassword + '\'' +
                '}';
    }
}

 

 

5. 編寫實體管理類映射接口UserMapper.java

  UserMapper接口和Mybatis的映射xml文件相對應,便於操作和使用

 

 1 package main.mapper;
 2 
 3 import main.pojo.User;
 4 
 5 import java.util.List;
 6 
 7 /*
 8 Comet_Fei
 9 2019/11/17
10 */
11 public interface UserMapper
12 {
13     int addUser(User user);
14     User getUser(String userPhoneNumber);
15     int deleteUser(String userPhoneNumber);
16     int setPassword(User user);
17     List<User> listUser();
18 
19 }

 

5. 編寫映射文件UserMapper.xml

  這類文件非常重要,會將數據庫表和Java代碼的pojo(bean)進行映射,極大的簡化了操作步驟,減小代碼量。

參數說明:

  • resultMap是數據庫表和實體的Map映射設置,在使用時,只要加入 resultMap=”userResultMap” 參數即可,如select語句;
  • parameterType是傳入的參數類型,如果傳入參數較多的話,可以使用實體類傳參,但是要寫明實體類全路徑;(還沒有學習複雜語句,所以這裏只是簡單介紹)
  • resultType是返回值類型,但是不能和resultMap同時存在;
  • 傳參方式如代碼所示,用  ${ } 標識參數,和接口一致;
  • namespace是全路徑,訪問到當前對應Map的接口文件;
  • 注意傳參的數據類型,如果是字符型或者String,需要用單引號包含,如: ‘${userName}’ 
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="main.mapper.UserMapper">
    <resultMap id="userResultMap" type="main.pojo.User">
        <result property="userPhoneNumber" column="user_phone_number"/>
        <result property="headPictureId" column="head_pictureId"/>
        <result property="rolePowerId" column="role_power_id"/>
        <result property="userName" column="user_name"/>
        <result property="userPersonalAutograph" column="user_personal_autograph"/>
        <result property="userPassword" column="user_password"/>
        <result property="userSex" column="user_sex"/>
        <result property="userEmail" column="user_email"/>
        <result property="userAddress" column="user_address"/>
        <result property="userUploadNumbers" column="user_upload_numbers"/>
    </resultMap>

    <!--    添加用戶-->
    <insert id="addUser" parameterType="main.pojo.User">
        INSERT INTO user(user_phone_number, user_name, user_password)
        VALUES ('${userPhoneNumber}', '${userName}', '${userPassword}');
    </insert>
    <!--    刪除用戶-->
    <delete id="deleteUser" parameterType="String">
        DELETE FROM user WHERE user_phone_number = '${userPhoneNumber}';
    </delete>

    <!--    獲得賬號為user_phone_number的用戶-->
    <select id="getUser" resultMap="userResultMap">
        SELECT * FROM user WHERE user_phone_number = '${userPhoneNumber}';
    </select>

    <!--    獲得用戶列表-->
    <select id="listUser" resultType="main.pojo.User">
        SELECT * FROM user;
    </select>

    <!--    找回密碼-->
    <update id="setPassword" parameterType="main.pojo.User">
        UPDATE user SET user_password = ${userPassword} WHERE user_phone_number = '${userPhoneNumber}';
    </update>

</mapper>

 

 

6. 最後是操作層(DAO)UserDao.java

  因為操作層有特定的業務,這裏只是一個示意而已。java裏面的main函數可以進行局部測試,便於和前端、控制器(servlet)等對接。

 1 package main.dao;
 2 
 3 import main.mapper.UserMapper;
 4 import main.pojo.User;
 5 import org.apache.ibatis.session.SqlSession;
 6 
 7 import java.io.IOException;
 8 
 9 /*
10 Comet_Fei
11 2019/11/17
12 */
13 public class UserDao {
14 //    定義dao內的sqlSession和映射接口mapper
15     private SqlSession sqlSession;
16     private UserMapper mapper;
17 
18     public UserDao()
19     {
20 //        通過工廠,初始化session;通過特有getMapper設置映射接口
21         sqlSession = DBTools.getSqlSession();
22         mapper = sqlSession.getMapper(UserMapper.class);
23     }
24 
25     //添加用戶 成功1 失敗0
26     public int addUser(String userPhoneNumber, String userPassword) throws IOException
27     {
28         //用戶的 手機號,姓名(默認手機號),密碼
29         User user = new User(userPhoneNumber,userPhoneNumber, userPassword);
30         int result = mapper.addUser(user);
31         sqlSession.commit();
32         System.out.println(result);
33         return result;
34     }
35 
36     //用戶登錄 短信 成功2;失敗0
37     public int right(String userPhoneNumber)
38     {
39         int result;
40         User user = mapper.getUser(userPhoneNumber);
41         if(user != null)
42         {
43             result = 2;//登錄成功
44         }
45         else
46         {
47             result = 0;//登錄失敗
48         }
49         sqlSession.commit();
50         return result;
51     }
52 
53     //用戶登錄 手機 密碼 成功2;密碼錯誤1;手機號錯誤0
54     public int right(String userPhoneNumber, String userPassword)
55     {
56         int result;
57         User user = mapper.getUser(userPhoneNumber);
58         if((user != null)&&(userPassword.equals(user.getUserPassword())))
59         {
60             result = 2;//登錄成功
61         }
62         else if(user != null)
63         {
64             result = 1;//密碼錯誤
65         }
66         else
67         {
68             result = 0;//此手機號未註冊
69         }
70         sqlSession.commit();
71         return result;
72     }
73 
74     //刪除用戶 成功是1,不成功是0
75     public int deleteUser(String userPhoneNumber)
76     {
77         int result = mapper.deleteUser(userPhoneNumber);
78         sqlSession.commit();
79         return result;
80     }
81 
82     //重設密碼
83     public int setPassword(String userPhoneNumber, String userPassword)
84     {
85         User user = new User(userPhoneNumber, userPhoneNumber, userPassword);
86         return mapper.setPassword(user);
87     }
88     public static void main(String[] args) throws IOException {
89         UserDao dao = new UserDao();
90 //        System.out.println(dao.deleteUser("111")); //刪除用戶
91 //        dao.addUser("111","111");// 添加用戶
92 //        System.out.println(dao.right("11"));//短信登錄;
93 //        System.out.println(dao.right("111","111"));//短信登錄;
94         System.out.println(dao.setPassword("111","111"));
95     }
96 }

 

以上為全部內容,之後還會寫一些關於IDEA操作上的快捷鍵,如,IDEA如何連接數據庫、快速生成pojo實體類等的博客。

如果運行異常,歡迎留言交流,共同進步!

這裏特別感謝博客: 

 

 

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

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

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

CSS(7)— 清除浮動(float)

CSS(7)— 通俗講解清除浮動

上一篇講了CSS浮動 博客地址:

一、理解清除浮動

1、為什麼要清除浮動

我們前面說過,浮動本質是用來做一些文字混排效果的,但是被我們拿來做布局用,則會有很多的問題出現。

由於浮動元素不再佔用原文檔流的位置,所以它會對後面的元素排版產生影響,為了解決這些問題,此時就需要在該元素中清除浮動。

準確地說,並不是清除浮動,而是清除浮動后造成的影響

2、清除浮動本質

清除浮動的本質: 主要為了解決父級元素因為子級浮動引起內部高度為0 的問題。

我們來詳細解釋下這句話

再解釋下就是在標準流下面一個父div沒有設置高度屬性,那麼它的高度就會被子元素的高度撐開。但是如果這個父div中的子元素是浮動的話,如果父div下面再有

一個兄弟div,那麼這個兄弟div就會遮擋這個父元素。這個現象也叫浮動溢出

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    .father {
        height: 200px;
        border: 1px solid red;
        width: 300px

    }
    .big {
        width: 100px;
        height: 100px;
        background-color: purple;
        float: left;
    }
    .small {
        width: 80px;
        height: 80px;
        background-color: blue;
        float: left;
    }
    .footer {
        width: 400px;
        height: 100px;
        background-color: pink;
    }
    </style>
</head>
<body>
    <div class="father"> 父div
        <div class="big">子div</div>
        <div class="small">子div</div>
    </div>
    <div class="footer">兄弟div</div>
</body>
</html>

運行結果

很明顯這裏,div1和div2已經上浮,而兄弟div就往上移動。這裏因為父div有文字所以佔了點高度,不然兄弟div會完全覆蓋父div。

當然我們可以通過設置父div的高度,來使它不被兄弟div所覆蓋。比如這裏設置 height: 200px;

在刷新下頁面

當父div設置高度后,被覆蓋的問題卻是解決了,但在很多時候我們是不會去設置父div的高度,因為很多時候我們都不知道父div的高度要設置多少。

所以這個時候需要思考解決這個問題。

二、清除浮動的方法

清除浮動的方法本質: 就是把父盒子里浮動的盒子圈到裏面,讓父盒子閉合出口和入口不讓他們出來影響其他元素。

在CSS中,clear屬性用於清除浮動。

基本語法格式

選擇器 {clear:屬性值;}

屬性值

1、額外標籤法

通過在浮動元素末尾添加一個空的標籤,例如

 <div style="clear:both"></div>

我們在上面的代碼添加

<body>
    <div class="father"> 父div
        <div class="big">子div</div>
        <div class="small">子div</div>
        <div style="clear:both"></div>  <!--  只需在父盒子里最後面添加這個空標籤添加clear:both屬性就可以清除浮動 -->
    </div>
    <div class="footer">兄弟div</div>
</body>

運行結果

完美解決了。

優點 通俗易懂,書寫方便。

缺點 添加無意義的標籤,結構化較差。

2、父級添加overflow屬性方法

可以通過觸發BFC的方式,可以實現清除浮動效果。(BFC後面會講)

可以給父級元素添加: overflow為 hidden|auto|scroll  都可以實現。

我們將上面代碼修改為

<body>
    <div class="father" style="overflow: hidden;"> 父div  <!-- 父元素添加 overflow: hidden --> 
        <div class="big">子div</div>
        <div class="small">子div</div>
    </div>
    <div class="footer">兄弟div</div>
</body>

也是能實現去除浮動的效果。

優點 代碼簡潔

缺點 內容增多時候容易造成不會自動換行導致內容被隱藏掉,無法显示需要溢出的元素。

3、使用after偽元素清除浮動

:after 方式為空元素的升級版,好處是不用單獨加標籤了** 

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用after偽元素清除浮動</title>
    <style>
    .clearfix:after {  /*正常瀏覽器 清除浮動*/
        content:"";
        display: block;
        height: 0;
        clear: both;
        visibility: hidden;
    }
    .clearfix {
        *zoom: 1;  /*zoom 1 就是ie6 清除浮動方式  *  ie7一下的版本所識別*/
    }
    .father {
        border: 1px solid red;
        width: 300px;

    }
    .big {
        width: 100px;
        height: 100px;
        background-color: purple;
        float: left;
    }
    .small {
        width: 80px;
        height: 80px;
        background-color: blue;
        float: left;
    }
    .footer {
        width: 400px;
        height: 100px;
        background-color: pink;
    }
    </style>
</head>
<body>
    <div class="father clearfix">
        <div class="big"></div>
        <div class="small"></div>
    </div>
    <div class="footer"></div>
</body>
</html>

優點 符合閉合浮動思想 結構語義化正確

缺點 由於IE6-7不支持:after,使用 zoom:1觸發 hasLayout。

注意: content:”.” 裏面盡量跟一個小點,或者其他,盡量不要為空,否則再firefox 7.0前的版本會有生成空格。

4、使用before和after雙偽元素清除浮動

使用方法 將上面的clearfix樣式替換成如下

    .clearfix:before, .clearfix:after {
        content: "";
        display: table;
    }
    .clearfix:after {
        clear: both;
    }

    .clearfix {
        *zoom: 1;
    }

優點 代碼更簡潔

缺點 由於IE6-7不支持:after,使用 zoom:1觸發 hasLayout。

5、總結

1、在網頁主要布局時使用:after偽元素方法並作為主要清理浮動方式.文檔結構更加清晰;
2、在小模塊如ul里推薦使用overflow:hidden;(同時留意可能產生的隱藏溢出元素問題);

你如果願意有所作為,就必須有始有終。(9)

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

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

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

Go語言Hello world(GOPATH和Go Module版)

本文是「vangoleo的Go語言學習筆記」系列文章之一。
官網:

往期回顧:

上一篇文章中,我們在Golang Playground中體驗了Go語言,編寫並運行了一個簡單的Hello World,相信大家對Go語言的語法有了一些了解。

學習一種編程語言,除了基本的語法,更重要的是要了解如何在實際的工程中使用它。本文中,我會和大家一起,從零開始,安裝Go語言,配置環境,安裝IDE,開發一個Hello World程序。這個Hello World版我會編寫兩個版本:GOPATH和Go Module版本。

Q:
本教程為什麼會編寫兩個版本?
A:
網上大部分Go語言Hello World都只簡單地介紹了GOPATH版本。但是從Go的1.11版本之後,已不再推薦使用GOPATH來構建應用了。也就是說GOPATH被認為是廢棄的,錯誤的做法。
正確的做法是使用Go Module。所以,有必要在教程中將這個信息告訴初學者,引導大家使用推薦的最佳實踐方式Go Module。
或許這也是本Hello World教程和網上大部分教程的區別吧。會從開發者的實際使用出發。介紹Go語言的發展歷史和最佳實踐。

安裝Go

使用Go語言開發,第一步肯定是安裝Go啦。

第一步:進入Go語言的官網https://golang.org。點擊“Download Go”。是的,就是那個傻傻的土撥鼠^_^

第二步:根據操作系統下載對應的軟件包進行安裝。
Golang對主流的操作系統都有支持,比如Windows,MacOS和Linux等。
本系列教程中,我會使用MacOS操作系統,所以選擇下載“Apple macOS”。大家要根據自己的操作系統進行下載。

第三步:安裝Go。
在MacOS下安裝Go很簡單,就是標準的DMG文件安裝,直接“下一步”就可以了。
第四步:確認Go是否安裝成功。
運行命令“go version”,會輸出類似於“go version go1.12.9 darwin/amd64”的內容。請確保包沒有任何錯誤發生。

配置環境

和其他開發語言類似,安裝了Go之後,還需要對開發環境進行相應的配置。比如在Java中,需要配置JAVA_HOME,MAVEN等。
Go開發相關的環境變量如下:

  • GOROOT:GOROOT就是Go的安裝目錄。
  • GOPATH:GOPATH保存go項目代碼。

GOROOT

GOROOT是Go的安裝路徑。Mac中安裝Go會自動配置好GOROOT,路徑為/usr/local/go。GOROOT在絕大多數情況下都不需要修改。以下是GOROOT目錄的內容(已省略了一些無關信息):

tree -L 2 /usr/local/go

./
├── bin
│   ├── go
│   └── gofmt
├── doc
│   ├── articles
│   └── docs.html
├── src
│   ├── errors
│   ├── fmt
│   ├── log
│   └── os

可以看到GOROOT下有bin,doc和src目錄。bin目錄下有我們熟悉的go和gofmt工具。可以認為GOOROOT和Java里的JDK目錄類似。

GOPATH

GOPATH是開發時的工作目錄。用於:

  • 保存編譯后的二進制文件。
  • go getgo install命令會下載go代碼到GOPATH。
  • import包時的搜索路徑。

關於GOPATH需要特別注意。在GO的1.11版本之前,GOPATH是必需的,且所有的Go項目代碼都要保存在GOPATH目錄下。Go的1.11版本之後,GO官方引入了Go Module。使用Go Module管理的項目可以放在GOPATH目錄外面。

使用GOPATH時,GO會在以下目錄中搜索包:

  1. GOROOT/src:該目錄保存了Go標準庫代碼。
  2. GOPATH/src:該目錄保存了應用自身的代碼和第三方依賴的代碼。

假設程序中引入了如下的包:

import "github.com/tom/hello-go/foo/bar"

第一步:Go會先去GOROOT的scr目錄中查找,很顯然它不是標準庫的包,沒找到。
第二步:繼續在GOPATH的src目錄去找,準確說是GOPATH/src/github.com/tom/hello-go/foo/bar這個目錄。如果該目錄不存在,會報錯找不到package。在使用GOPATH管理項目時,需要按照GO尋找package的規範來合理地保存和組織Go代碼。

Go的這個“將所有代碼都放置在GOPATH中”的設計,的確是和其他主流語言很不一樣。不管Go官方是出於什麼考慮,這個設計在實際使用中,的確給開發者造成了很大的不便和理解上的困難。甚至直接勸退了很多Go的初學者。
萬幸的是,Go Module正式發布了。Go Module的發布解決了困擾Go語言長達十年的代碼組織,依賴管理問題。

說明:關於GOPATH和Go Module的歷史淵源,詳細使用,會在另一篇進行說明。本文還是聚焦在Hello World入門。

另外,由於某些原因,Go的某些託管在Google倉庫中的代碼在國內是無法訪問的。如果使用Go Module,我們可以設置GOPROXY,讓Go從GOPROXY下載Go代碼,速度更快。國內用戶可以設置GOPROXY為,使用如下命令來設置GOPROXY:

export GOPROXY=https://goproxy.cn

關於環境配置,總結下來就是:

  • 如果使用Go Module(推薦的),設置export GOPROXY=。
  • 如果使用GOPATH(遺留的,被廢棄的),需要設置GOPATH到本地的某個目錄。

安裝IDE

目前比較常用的IDE有:

  • Visual Studio Code
  • GoLand

Visual Studio Code是微軟開發的一款開源的,輕量級的文本編輯器。通過安裝Go插件,可以用於Go語言的開發。GoLand是JetBrains公司開發的,專業的Go語言開發IDE。

推薦使用GoLand。很多人都說Visual Studio Code更輕量級,但作為一款每天都要重度使用的,需要靠它吃飯的工具,我們需要的是功能全面。尤其是當你需要完備的調試,需要強大的IDE智能輔助功能時,相信你會選擇更專業的GoLand。

GoLand的官方主頁為https://www.jetbrains.com/go/,點擊“Download”即可下載

注意
GoLand使用的是和IntelliJ IDEA一樣的框架,是用Java語言開發的。你需要安裝Java環境才可以運行GoLand哦。

GoLand是收費軟件,只有30天的試用期。試用期結束后,需要購買授權。當然在天朝,我們都習慣不花錢用軟件。大家可以自行百度或google搜索一下。

Hello World(GOPATH版)

第一步:設置GOPATH
首先設置GOPATH,假設GOPATH設置為$HOME/worspace/go
第二步:創建子目錄
進入$HOME/workspace/go目錄。新建子目錄src。然後再src中新建子目錄hello。在hello目錄,新建一個hello-world.go文件:
目錄結構應該如下所示:

$HOME
  workspace
    go
      src
        hello
          hello-world.go

第三步:創建hello-world.go文件:

package main
import "fmt"
func main() {
    fmt.Println("hello world")
}

第四步:執行go build
$HOME/workspace/go目錄執行命令:

go build

會生成一個可執行二進制文件:hello。如果是Windows系統,會生成hello.exe文件。
第五步:運行hello文件:

./hello

hello world

輸出“hello world”。

Hello World(GO Module版)

第一步:創建項目的根目錄
任意創建一個目錄(可以不在GOPATH中),假設是$HOME/tmp/hello。
第二步:初始化Go模塊
執行命令:

go mod init github.com/vangoleo/hello

該命令會將hello目錄初始化為一個Go module,並生成一個$HOME/tmp/hello/go.mod文件。內容如下:

module github.com/vangoleo/hello

go 1.12

第三步:編寫hello.go文件
編寫文件$HOME/tmp/hello/hello.go:

package main

import (
    "fmt"
    "rsc.io/quote"
)

func main() {
    fmt.Println(quote.Hello())
}

第四步:編輯go.mod文件:
在實際項目中,都會使用到第三方庫。可以在Go Module中添加項目的依賴。本例中,我們會添加一個quote依賴,該依賴會打印當前語言的“Hello World”,比如,如果是中文環境,會打印“你好,世界”。
編輯go.mod文件,添加quote依賴:

module github.com/vangoleo/hello

go 1.12

require rsc.io/quote v1.5.2

第五步:執行go build
執行go build,會生成可執行文件$HOME/tmp/hello/hello
第六步:執行hello文件
執行hello文件,輸出“你好,世界”。

最後

本文中,我們從下載安裝,配置Go環境開始,並完成了GOPATH和Go Module兩個版本的Hello World應用。如果你跟着我一步一步完成了這些步驟,恭喜你!!!已經完成了第一個真正的Go應用,並且使用了正確的Go Module來管理Go程序。

接下來,我們可以開始學習Go語言的語法部分(基本數據類型,判斷,循環等)了。咋們下期見。

本文由 發布

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

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※帶您來看台北網站建置台北網頁設計,各種案例分享

小三通物流營運型態?

※快速運回,大陸空運推薦?

揭示太陽能遠景 日政商要角300人與會 目標主力電源

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

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

【其他文章推薦】

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

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

COP26主題定調金融 聯合國氣候特使:零碳帶來當代最大商機

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

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

【其他文章推薦】

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※帶您來看台北網站建置台北網頁設計,各種案例分享

小三通物流營運型態?

※快速運回,大陸空運推薦?

電動機車 Gogoro 與時尚結合,邀請派對潮男試乘

先前在媒體上熱烈討論的電動車 Gogoro 繼續以生活品味為主打形象,這次與時裝雜誌的活動結合,試圖要把騎機車這件事事情變得更潮。Gogoro 獲邀參與 GQ 紳裝正義 2016 SUIT WALK 遊行與派對活動。

為響應 GQ 派對主題,Gogoro 也舉辦「紳士有禮」體驗,只要消費者在 Taipei 101 四樓 Gogoro 展區完成最新智慧解鎖、拍照分享後即可獲得神秘限定騎乘邀請函,現場亦可索取潮男限定試騎卷,憑卷在 3 月 14 日白色情人節到 Gogoro 信義全球體驗中心試騎,即可獲得 Gogoro 限量潮 T 一件,數量有限敬請把握!   Gogoro 執行長暨創辦人陸學森表示:「Gogoro 非常榮幸可以成為這次時尚盛會中唯一的二輪交通品牌,我們希望鼓勵無論男性女性,時時刻刻都用各式方式展現自己的風格,例如 Smartscooter® 智慧雙輪可以讓消費者更換不同設計的面板,也是希望突破機車只是交通工具的想像,讓智慧雙輪不僅可以帶你帥氣的在城市間遊走、也可以透過不同的面板造型與設計,讓車主展現你獨一無二的個人風格。」  

 
▲ 全球最時尚大叔 Nick Wooster 稱讚 Gogoro 智慧雙輪時尚外型最合紳士出遊。(Source:Gogoro)   紳裝正義活動到 2016 年已經是第三屆舉行,從 2014 年開始主辦人就串連台灣、香港、新加坡與上海等亞洲時尚重地,邀請所有的型男紳士在每年白色情人節期間,穿上最時尚、最具個人風格的西裝到街頭遊行展現紳士魅力。此次 Gogoro 除了是唯一受邀參加遊行的交通工具品牌之外,遊行後也與其他時尚品牌如 Porches、HUGO BOSS、瑞士頂級 Zenith 真力時手錶等,於 Taipei 101 四樓參與 GQ 紳裝正義派對,在現場展現如何透過科技時尚魅力、展現自我風格。  

▲ 時尚男孩小杰帶領 Gogoro 型男軍團參與 GQ 紳裝正義遊行。(Source:Gogoro)   (首圖說明:Gogoro 型男軍團參與GQ SUIT WALK 2016 於台北101時尚派對。Source:Gogoro)   (本文授權轉載自《》─〈〉)

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

【其他文章推薦】

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

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

寶馬 i 系電動車2015年全年銷量為29513輛

近日,寶馬集團發佈了寶馬 2015年的財報, 2015年,寶馬集團銷量達到2,247,485輛,同比增長6.1%。(2014年:2,117,965輛)。

2015年,BMW品牌全球銷量增長5.2%,至1,905,234輛(2014年:1,811,719輛)。其中,BMW 2系、4系以及BMW X家族表現突出,促進了銷量增長。

另外要提一下寶馬的新能源車型 BMW i 系,該車型實現了65.9%的增長,共交付客戶29,513輛(2014年:17,793輛),其中,BMW i3在全球範圍的銷量增幅為49.9%,共售出24,057輛(2014年:16,052輛),BMW i8銷量達到5,456輛(2014年:1,741輛)。

寶馬其他車型銷量還包括 MINI 品牌:交付量增長 12.0%,達338,466 輛(2014年:302,183 輛);勞斯萊斯:全球共交付客戶3,785輛,其中魅影和古斯特對銷量做出最大貢獻。另外,2015寶馬集團的全球前四大市場是中國、美國、德國和英國。

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

【其他文章推薦】

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※帶您來看台北網站建置台北網頁設計,各種案例分享

小三通物流營運型態?

※快速運回,大陸空運推薦?

java面試題-Java集合相關

1. ArrayList 和Vector 的區別

  ArrayList和Vector底層實現原理都是一樣得,都是使用數組方式存儲數據

  Vector是線程安全的,但是性能比ArrayList要低。

  ArrayList,Vector主要區別為以下幾點:

   (1):Vector是線程安全的,源碼中有很多的synchronized可以看出,而ArrayList不是。導致Vector效率無法和ArrayList相比;

      (2):ArrayList和Vector都採用線性連續存儲空間,當存儲空間不足的時候,ArrayList默認增加為原來的50%,Vector默認增加為原來的一倍;

   (3):Vector可以設置capacityIncrement,而ArrayList不可以,從字面理解就是capacity容量,Increment增加,容量增長的參數。

 

2.說說ArrayList,Vector, LinkedList 的存儲性能和特性

  ArrayList採用的數組形式來保存對象,這種方法將對象放在連續的位置中,所以最大的缺點就是插入和刪除的時候比較麻煩,查找比較快;

  Vector使用了sychronized方法(線程安全),所以在性能上比ArrayList要差些.

  LinkedList採用的鏈表將對象存放在獨立的空間中,而且在每個空間中還保存下一個鏈表的索引。使用雙向鏈表方式存儲數據,按序號索引數據需要前向或後向遍曆數據,所以索引數據慢,是插入數據時只需要記錄前後項即可,所以插入的速度快。

 

3.快速失敗(fail-fast) 和安全失敗(fail-safe) 的區別是什麼?

  1.快速失敗

  原理是:

        迭代器在遍歷時直接訪問集合中的內容,並且在遍歷過程中使用一個modCount變量。集合在被遍歷期間如果內容發生變化,就會改變modCount的值。每當迭代器使用hasNext()或next()遍歷下一個元素之前,都會先檢查modCount變量是否為expectmodCount值。如果是的話就返回遍歷;否則拋出異常,終止遍歷。

  查看ArrayList源碼,在next方法執行的時候,會執行checkForComodification()方法。

       

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1 ;
             return (E) elementData[lastRet = i];
        }
        final  void checkForComodification() {
             if (modCount != expectedModCount)
                 throw  new ConcurrentModificationException();
        }

  這裏異常的拋出條件是modCount != expectedModCount這個條件。如果集合發生變化時修改modCount值剛好又設置為了expectedModCount值,則異常不會拋出。因此,不能依賴於這個異常是否拋出而進行併發操作,這個異常只建議用於檢測併發修改的bug。

  2.安全失敗

    採用安全失敗機制的集合容器,在遍歷時不是直接在集合上訪問的,而是先複製原有集合內容,在拷貝的集合上進行遍歷。

  原理:

          由於迭代時是對原集合的拷貝進行遍歷,所以在遍歷過程中對原集合所做的修改並不能被迭代器檢測到,所以不會觸發ConcurrentModificationException,例如CopyOnWriteArrayList。

  缺點:

          基於拷貝內容的優點是避免了ConcurrentModificationException,但同樣地,迭代器並不能訪問到修改後的內容。即:迭代器遍歷的是開始遍歷那一刻拿到的集合拷貝,在遍歷期間原集合發生的修改迭代器是不知道的。

  場景:

          Java.util.concurrent包下的容器都是安全失敗的,可以在多線程下併發使用,併發修改。

        快速失敗和安全失敗都是對迭代器而言的。快速失敗:當在迭代一個集合時,如果有另外一個線程在修改這個集合,就會跑出ConcurrentModificationException,java.util下都是快速失敗。安全失敗:在迭代時候會在集合二層做一個拷貝,所以在修改集合上層元素不會影響下層。在java.util.concurrent包下都是安全失敗。

 

4.HashMap 的數據結構

  HashMap的主幹類是一個Entry數組(jdk1.7) ,每個Entry都包含有一個鍵值隊(key-value).

  我們可以看一下源碼:

static  class Entry<K,V> implements Map.Entry<K,V> {
         final K key;
        V value;
        Entry <K,V> next; // 存儲指向下一個Entry的引用,單鏈表結構
        int hash; // 對key的hashcode值進行hash運算後得到的值,存儲在Entry,避免重複計算

        /**
         * Creates new entry.
         */ 
        Entry( int h, K k, V v, Entry<K,V> n) {
            value = v;
            next = n;
            key = k;
            hash = h;
        }

  所以,HashMap的整體結果如下

  

 

   簡單來說,HashMap由數組+鏈表組成的,數組是HashMap的主體,鏈表則是主要為了解決哈希衝突而存在的,如果定位到的數組位置不含鏈表(當前entry的next指向null ),那麼對於查找,添加等操作很快,僅需一次尋址即可;如果定位到的數組包含鏈表,對於添加操作,其時間複雜度為O(n),首先遍歷鏈表,存在即覆蓋,否則新增;對於查找操作來講,仍需遍歷鏈表,然後通過key對象的equals方法逐一比對查找。所以,性能考慮,HashMap中的鏈表出現越少,性能才會越好。

 

5.HashMap 的工作原理

  HashMap基於hashing原理,我們通過put()和get()方法存儲和獲取對象,當我們將鍵值對傳遞給put()方法時,它調用鍵對象的hashCode()方法來計算hashcode,讓後找到bucket位置來存儲值對象。當獲取對象時,通過鍵對象的equals()方法找到正確的鍵值對,然後返回對象。

  我們看一下put()源碼:

public V put(K key, V value) {
         // 當key為null,調用putForNullKey方法,保存null與table第一個位置中,這是HashMap允許為null的原因
        if (key == null )
             return putForNullKey( value);
         // 計算key的hash值
        int hash = hash(key.hashCode());                   // 計算key hash值在table數組中的位置
        int i = indexFor(hash, table.length);              // 從i出開始迭代e,找到key保存的位置
        for (Entry<K, V> e = table[i]; e != null ; e = e.next) {
            Object k;
            // 判斷該條鏈上是否有hash值相同的(key相同)
             // 若存在相同,則直接覆蓋value,返回舊value 
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;     // 舊值=新值 
                e.value = value;
                e.recordAccess( this );
                 return oldValue;      // 返回舊值
            }
        }
        // 修改次數增加1 
        modCount++ ;
         // 將key、value添加至i位置處
        addEntry(hash, key, value, i);
         return  null ;
    }

  通過源碼我們可以清晰看到HashMap保存數據的過程為:首先判斷key是否為null,若為null,則直接調用putForNullKey方法。若不為空則先計算key的hash值,然後根據hash值搜索在table數組中的索引位置,如果table數組在該位置處有元素,則通過比較是否存在相同的key,若存在則覆蓋原來key的value,否則將該元素保存在鏈頭(最先保存的元素放在鏈尾)。若table在該處沒有元素,則直接保存。

  get()源碼: 

public V get(Object key) {
         // 若為null,調用getForNullKey方法返回相對應的value 
        if (key == null )
             return getForNullKey();
         // 根據該key的hashCode值計算它的hash碼   
        int hash = hash(key.hashCode());
         // 取出table數組中指定索引處的值
        for (Entry<K, V> e = table[indexFor(hash, table.length)]; e != null ; e = e .next) {
            Object k;
            // 若搜索的key與查找的key相同,則返回相對應的value 
            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                 return e .value;
        }
        return  null ;
    }

  在這裡能夠根據key快速的取到value除了和HashMap的數據結構密不可分外,還和Entry有莫大的關係,在前面就提到過,HashMap在存儲過程中並沒有將key,value分開來存儲,而是當做一個整體key-value來處理的,這個整體就是Entry對象。同時value也只相當於key的附屬而已。在存儲的過程中,系統根據key的hashcode來決定Entry在table數組中的存儲位置,在取的過程中同樣根據key的hashcode取出相對應的Entry對象。

 

6.Hashmap 什麼時候進行擴容呢?

  這裏我們再來複習put的流程:當我們想一個HashMap中添加一對key-value時,系統首先會計算key的hash值,然後根據hash值確認在table中存儲的位置。若該位置沒有元素,則直接插入。否則迭代該處元素鏈表並依此比較其key的hash值。如果兩個hash值相等且key值相等(e.hash == hash && ((k = e.key) == key || key.equals(k))),則用新的Entry的value覆蓋原來節點的value。如果兩個hash值相等但key值不等,則將該節點插入該鏈表的鏈頭。具體的實現過程見addEntry方法,如下:

void addEntry( int hash, K key, V value, int bucketIndex) {
         // 獲取bucketIndex處的Entry 
        Entry<K, V> e = table[bucketIndex];
         // 將新創建的Entry放入bucketIndex索引處,並讓新的Entry指向原來的Entry 
        table[bucketIndex] = new Entry<K, V> (hash, key, value, e);
         // 若HashMap中元素的個數超過極限了,則容量擴大兩倍
        if ( size++ >= threshold)
            resize( 2 * table.length);
    }

  這個方法中有兩點需要注意:

      一是鏈的產生。這是一個非常優雅的設計。系統總是將新的Entry對象添加到bucketIndex處。如果bucketIndex處已經有了對象,那麼新添加的Entry對象將指向原有的Entry對象,形成一條Entry鏈,但是若bucketIndex處沒有Entry對象,也就是e==null,那麼新添加的Entry對象指向null ,也就不會產生Entry鏈了。

      二、擴容問題。

      隨著HashMap中元素的數量越來越多,發生碰撞的概率就越來越大,所產生的鏈表長度就會越來越長,這樣勢必會影響HashMap的速度,為了保證HashMap的效率,系統必須要在某個臨界點進行擴容處理。該臨界點在當HashMap中元素的數量等於table數組長度*加載因子。但是擴容是一個非常耗時的過程,因為它需要重新計算這些數據在新table數組中的位置並進行複製處理。所以如果我們已經預知HashMap中元素的個數,那麼預設元素的個數能夠有效的提高HashMap的性能。

 

 7.HashSet怎樣保證元素不重複

  都知道HashSet中不能存放重複的元素,有時候可以用來做去重操作。但是其內部是怎麼保證元素不重複的呢?

  打開HashSet源碼,發現其內部維護一個HashMap:

public  class HashSet<E> 
    extends AbstractSet <E> 
    implements Set <E> , Cloneable, java.io.Serializable
{
    static final long serialVersionUID = - 5024744406713321676L ;

    private transient HashMap<E,Object> map;

    private  static final Object PRESENT = new Object();

 
    public HashSet() {
        map = new HashMap<> ();
    } 
  ...
}

  HashSet的構造方法其實就是在內部實例化了一個HashMap對象,其中還會看到一個static final的PRESENT變量;

  想知道為什麼HashSet不能存放重複對象,那麼第一步看看它的add方法進行的判重,代碼如下

    public  boolean add(E e) {
         return map.put(e, PRESENT)== null ;
    }

  其實看add()方法,這時候答案已經出來了:HashMap的key是不能重複的,而這裏HashSet的元素又是作為了map的key,當然也不能重複了

  順便看一下HashMap裏面又是怎麼保證key不重複的,代碼如下:

public V put(K key, V value) {
     if (table == EMPTY_TABLE) {
        inflateTable(threshold);
    }
    if (key == null )
         return putForNullKey(value);
     int hash = hash(key);
     int i = indexFor(hash, table.length);
     for (Entry<K,V> e = table[i]; e ! = null ; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess( this );
             return oldValue;
        }
    }

    modCount ++ ;
    addEntry(hash, key, value, i);
    return  null ;
}

  其中最關鍵的一句: 

if (e.hash == hash && ((k = e.key) == key || key.equals(k)))

  調用了對象的hashCode和equals方法進行判斷,所以又得到一個結論:若要將對象存放到HashSet中並保證對像不重複,應根據實際情況將對象的hashCode方法和equals方法進行重寫

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

【其他文章推薦】

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

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?