主頁 > 後端開發 > 面試官:你說你精通 Docker,那你來詳細說說 Dockerfile 吧

面試官:你說你精通 Docker,那你來詳細說說 Dockerfile 吧

2020-10-20 17:00:32 後端開發

接上一篇:30分鐘快速上手Docker,看這篇就對了!

一、 帶著問題學Dockerfile

1、疑問

我們都知道從遠程倉庫可以pull一個tomcat等鏡像下來,然后docker run啟動容器,然后docker exec -it 容器id /bin/bash進入容器,往webapps下仍我們的程式,等等這一系列操作,都需要人工一步步的去操作,那我問你:你沒qa和生產環境的部署權限,你咋操作這些?這就需要將所有人工一步步操作的地方都寫到Dockerfile檔案里,然后將檔案給到運維人員,他們build成鏡像然后進行啟動,

2、舉例

比如:你要用tomcat部署一個war包,這時候你的Dockerfile檔案內容會包含如下:

  • 將tomcat從遠程倉庫拉下來

  • 進入到tomcat的webapps目錄

  • 將宿主機上的war包扔到容器的webapps目錄下

然后運維拿著這個Dockerfile進行build成image,在run一下啟動容器,大功告成

3、好處

上面的例子好處不難發現

  • Dockerfile解放了手工操作很多步驟

  • Dockerfile保證了環境的統一

再也不會出現:QA是正常的,線上就是不行的情況了(前提是由于環境問題導致的 ),因為Dockerfile是同一份,大到環境,小到版本全都一致,再有問題那也是代碼問題,節省了和運維人員大量“親密接觸”的時間,

二、什么是Dockerfile

知道Dockerfile是干嘛的了,那Dockerfile的定義到底是啥呢?

Dockerfile中文名叫鏡像描述檔案,是一個包含用于組合鏡像目錄的文本檔案,也可以叫“腳本”,他通過讀取Dockerfile中的指令安裝步驟自動生成鏡像,

補充:檔案名稱必須是:Dockerfile

三、Dockerfile命令

1、構建鏡像命令

docker build -t 機構/鏡像名稱<:tags> Dockerfile目錄
# 比如如下,最后一個.代表當前目錄,因為我的Dockerfile檔案就在這,也可以用絕對路徑
docker build -t chentongwei.com/mywebapp:1.0.0 .
# 然后執行docker images 進行查看會發現有我們剛才構建的鏡像
docker images

 

面試官:你說你精通 Docker,那你來詳細說說 Dockerfile 吧

2、基礎命令

2.1、FROM

# 制作基準鏡像
FROM 鏡像
# 比如我們要發布一個應用到tomcat里,那么的第一步就是FROM tomcat
FROM tomcat<:tags>

先有個印象,下面會實戰操作,

2.2、LABEL&MAINTAINER

# MAINTAINER,一般寫個人id或組織id
# LABEL 就是注釋,方便閱讀的,純注釋說明,不會對Dockerfile造成任何影響
# 比如:
MAINTAINER baidu.com
LABEL version = "1.0.0"
LABEL description = "我們是大百度!"
# ...等等描述性資訊,純注釋,

 

2.3、WORKDIR

# 類似于Linux中的cd命令,但是他比cd高級的地方在于,我先cd,發現沒有這個目錄,我就自動創建出來,然后在cd進去
WORKDIR /usr/local/testdir

這個路徑建議使用絕對路徑,

2.4、ADD&COPY

2.4.1、COPY

# 將1.txt拷貝到根目錄下,它不僅僅能拷貝單個檔案,還支持Go語言風格的通配符,比如如下:
COPY 1.txt /
# 拷貝所有 abc 開頭的檔案到testdir目錄下
COPY abc* /testdir/
# ? 是單個字符的占位符,比如匹配檔案 abc1.log
COPY abc?.log /testdir/

 

2.4.2、ADD

# 將1.txt拷貝到根目錄的abc目錄下,若/abc不存在,則會自動創建
ADD 1.txt /abc
# 將test.tar.gz解壓縮然后將解壓縮的內容拷貝到/home/work/test
ADD test.tar.gz /home/work/test

 

docker官方建議當要從遠程復制檔案時,盡量用curl/wget命令來代替ADD,因為用ADD的時候會創建更多的鏡像層,鏡像層的size也大,

2.4.3、對比

  • 二者都是只復制目錄中的檔案,而不包含目錄本身,

  • COPY能干的事ADD都能干,甚至還有附加功能,

  • ADD可以支持拷貝的時候順帶解壓縮檔案,以及添加遠程檔案(不在本宿主機上的檔案),

  • 只是檔案拷貝的話可以用COPY,有額外操作可以用ADD代替,

2.5、ENV

# 設定環境常量,方便下文參考,比如:
ENV JAVA_HOME /usr/local/jdk1.8
# 參考上面的常量,下面的RUN指令可以先不管啥意思,目的是想說明下文可以通過${xxx}的方式參考
RUN ${JAVA_HOME}/bin/java -jar xxx.jar

ENV設定的常量,其他地方都可以用${xxx}來參考,將來改的時候只改ENV的變數內容就行,

3、運行指令

一共有三個:RUN&CMD&ENTRYPOINT

1、RUN

1.1、執行時機

RUN指令是在構建鏡像時運行,在構建時能修改鏡像內部的檔案,

1.2、命令格式

命令格式不光是RUN獨有,而是下面的CMD和ENTRYPOINT都通用,

 

  • SHELL命令格式

比如

RUN yum -y install vim

 

  • EXEC命令格式

比如

RUN ["yum","-y","install","vim"]

 

  • 二者對比

SHELL:當前shell是父行程,生成一個子shell行程去執行腳本,腳本執行完后退出子shell行程,回到當前父shell行程,

EXEC:用EXEC行程替換當前行程,并且保持PID不變,執行完畢后直接退出,不會退回原來的行程,

總結:也就是說shell會創建子行程執行,EXEC不會創建子行程,

 

  • 推薦EXEC命令格式

1.3、舉例

舉個最簡單的例子,構建鏡像時輸出一句話,那么在Dockerfile里寫如下即可:

RUN ["echo", "image is building!!!"]

 

再比如我們要下載vim,那么在Dockerfile里寫如下即可:

RUN ["yum","-y","install","vim"]

 

莫慌,下面會有實戰來完完整整的演示,

2、CMD

2.1、執行時機

容器啟動時執行,而不是鏡像構建時執行,

2.2、解釋說明

在容器啟動的時候執行此命令,且Dockerfile中只有最后一個ENTRYPOINT會被執行,推薦用EXEC格式,重點在于如果容器啟動的時候有其他額外的附加指令,則CMD指令不生效,

2.3、舉例

CMD ["echo", "container starting..."]

 

3、ENTRYPOINT

3.1、執行時機

容器創建時執行,而不是鏡像構建時執行,

3.2、解釋說明

在容器啟動的時候執行此命令,且Dockerfile中只有最后一個ENTRYPOINT會被執行,推薦用EXEC格式,

3.3、舉例

ENTRYPOINT ["ps","-ef"]

 

4、代碼演示

4.1、執行時機演示

FROM centos
RUN ["echo", "image building!!!"]
CMD ["echo", "container starting..."]
docker build -t chentongwei.com/test-docker-run .

 

構建鏡像的程序中發現我們RUN的image building!!! 輸出了,所以RUN命令是在鏡像構建時執行,而并沒有container starting…的輸出,

面試官:你說你精通 Docker,那你來詳細說說 Dockerfile 吧

docker run chentongwei.com/test-docker-run

 

結果:container starting...,足以發現CMD命令是在容器啟動的時候執行,

4.2、CMD和ENTRYPOINT演示

ENTRYPOINT和CMD可以共用,若共用則他會一起合并執行,如下Demo:

 

FROM centos
RUN ["echo", "image building!!!"]
ENTRYPOINT ["ps"]
CMD ["-ef"]
# 構建鏡像
docker build -t chentongwei.com/docker-run .
# 啟動容器
docker run chentongwei.com/docker-run

 

輸出結果:

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 13:02 ?        00:00:00 ps -ef

 

他給我們合并執行了:ps -ef,這么做的好處在于如果容器啟動的時候添加額外指令,CMD會失效,可以理解成我們可以動態的改變CMD內容而不需要重新構建鏡像等操作,比如

docker run chentongwei.com/docker-run -aux

 

輸出結果:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  2.0  0.0  46340  1692 ?        Rs   13:02   0:00 ps -aux

 

結果直接變成了 ps -aux,CMD命令不執行了,但是ENTRYPOINT一定執行,這也是CMD和ENTRYPOINT的區別之一,

四、實戰

1、部署應用到tomcat

1.1、準備作業

# 在服務器上創建test-dockerfile檔案夾
mkdir test-dockerfile
# 進入test-dockerfile目錄
cd test-dockerfile
# 創建需要部署到tomcat的應用
mkdir helloworld
# 在helloworld目錄下創建index.html寫上hello dockerfile
cd helloworld/
vim index.html

 

效果如下圖:

面試官:你說你精通 Docker,那你來詳細說說 Dockerfile 吧

面試官:你說你精通 Docker,那你來詳細說說 Dockerfile 吧

1.2、Dockerfile

# 在test-dockerfile目錄下創建Dockerfile檔案,注意大寫D,沒有后綴,
touch Dockerfile

 

在Dockerfile里寫上如下內容

FROM tomcat:latest
MAINTAINER baidu.com
WORKDIR /usr/local/tomcat/webapps
ADD helloworld ./helloworld

 

逐行解釋:

第一行:因為我們要部署應用到tomcat上,所以需要從遠程倉庫里拉取tomcat作為基礎鏡像,

第二行:描述性東西,還可以LABEL XXX XXX 添加更詳細的注釋資訊,

第三行:cd到/usr/local/tomcat/webapps,發現沒有這個目錄,我就自動創建出來,然后在cd進去

為什么是這個目錄呢?因為當我們制作完鏡像把容器run起來的時候tomcat的位置是在/usr/local/tomcat,加個/webapps是因為我們要將我們的應用程式扔到webapps下才能跑,如果懵,繼續往下看就懂了,

第四行:tomcat有了,tomcat的webapps我們也cd進去了,那還等啥?直接把我們的應用程式拷貝到webapps下就歐了,所以ADD命令宿主機上的helloworld檔案夾下的內容拷貝到當前目錄(webapps,上一步剛cd進來的)的helloworld檔案夾下,

1.3、制作鏡像

docker build -t baidu.com/test-helloworld:1.0.0 .

 

. 代表當前目錄,這些命令不懂的看上面的【三、Dockerfile命令】,都是上面提到的,沒新知識,

命令執行后的結果

[root@izm5e3qug7oee4q1y4opibz test-dockerfile]# docker build -t baidu.com/test-helloworld:1.0.0 .
Sending build context to Docker daemon  3.584kB
Step 1/4 : FROM tomcat:latest
 ---> 1b6b1fe7261e
Step 2/4 : MAINTAINER baidu.com
 ---> Running in ac58299b3f38
Removing intermediate container ac58299b3f38
 ---> 5d0da6398f7e
Step 3/4 : WORKDIR /usr/local/tomcat/webapps
 ---> Running in 1c21c39fc58e
Removing intermediate container 1c21c39fc58e
 ---> 9bf9672cd60e
Step 4/4 : ADD helloworld ./helloworld
 ---> 6d67c0d48c20
Successfully built 6d67c0d48c20
Successfully tagged baidu.com/test-helloworld:1.0.0

 

好像分了1/2/3/4步呢?這是啥意思,這是鏡像分層的概念,下面說,現在只看到SuccessFully就哦了,

再查看下我們的鏡像真實存在了嗎?

docker images

 

完美

面試官:你說你精通 Docker,那你來詳細說說 Dockerfile 吧

1.4、啟動容器

docker run -d -p 8100:8080  baidu.com/test-helloworld:1.0.0
# 然后docker ps查看容器是否存在
docker ps

 

瀏覽器訪問:http://服務器ip:8100/helloworld/index.html,很完美,這個helloworld就是我們Dockerfile里自己的應用程式,

面試官:你說你精通 Docker,那你來詳細說說 Dockerfile 吧

1.5、進入容器

docker exec -it 730f9e144f68 /bin/bash

 

面試官:你說你精通 Docker,那你來詳細說說 Dockerfile 吧

疑問1:怎么進入容器后直接在webapps目錄下,這就是因為我們這個鏡像是用Dockerfile制作的,Dockerfile上面我們自己WORKDIR到webapps目錄下的呀,

答疑1:我們ls下可以看到Dockerfile里的helloworld應用就在這里

root@730f9e144f68:/usr/local/tomcat/webapps# ls
helloworld

 

答疑2:Dockerfile里WORKDIR /usr/local/tomcat/webapps了,為啥是這個目錄也很清晰了,容器里的tomcat就在這

root@730f9e144f68:/usr/local/tomcat/webapps# pwd
usr/local/tomcat/webapps

 

2、從0制作Redis鏡像

一般沒人制作Redis鏡像,Redis有官方的docker鏡像,docker pull一下就行,這里是為了演示上面的命令,從0到1的程序,

2.1、準備作業

1.去官網下載Redis的原始碼包,因為我們演示的是Redis從無到有的程序,

2.準備Redis的組態檔redis-6379.conf

2.2、Dockerfile

# 將Redis運行在centos上
FROM centos
# 安裝Redis所需要的基礎庫
RUN ["yum", "install", "-y", "gcc", "gcc-c++", "net-tools", "make"]
# 將Redis目錄放到/usr/local
WORKDIR /usr/local
# 別忘了ADD命令自帶解壓縮的功能
ADD redis-4.0.14.tag.gz .
WORKDIR /usr/local/redis-4.0.14/src
# 編譯安裝Redis
RUN make && make install
WORKDIR /usr/local/redis-4.0.14
# 將組態檔仍到Redis根目錄
ADD redis-6379.conf .
# 宣告容器中Redis的埠為6379
EXPOSE 6379
# 啟動Redis  redis-server redis-6379.conf
CMD ["redis-server", "redis-6379.conf"]

 

2.3、制作鏡像&&啟動容器

# 制作鏡像
docker build -t chentongwei.com/docker-redis .
# 查看
docker images
# 啟動容器
docker run -p 6379:6379 chentongwei.com/docker-redis

 

上面三套小連招執行完后redis就起來了,可以redis-cli去鏈接了,也可以docker exec進入容器去查看,

3、用docker部署jar包

FROM openjdk:8-jdk-alpine:latest
ADD target/helloworld-0.0.1-SNAPSHOT.jar /helloworld.jar
ENTRYPOINT ["java","-jar","/helloworld.jar"]

 

然后build成鏡像再run啟動容器,很簡單粗暴,

五、補充:鏡像分層的概念

1、Dockerfile

FROM tomcat:latest
MAINTAINER baidu.com
WORKDIR /usr/local/tomcat/webapps
ADD helloworld ./helloworld

 

2、鏡像分層

就拿上面的Dockerfile來build的話,執行程序是如下的:

Sending build context to Docker daemon  3.584kB
Step 1/4 : FROM tomcat:latest
 ---> 1b6b1fe7261e
Step 2/4 : MAINTAINER baidu.com
 ---> Running in ac58299b3f38
Removing intermediate container ac58299b3f38
 ---> 5d0da6398f7e
Step 3/4 : WORKDIR /usr/local/tomcat/webapps
 ---> Running in 1c21c39fc58e
Removing intermediate container 1c21c39fc58e
 ---> 9bf9672cd60e
Step 4/4 : ADD helloworld ./helloworld
 ---> 6d67c0d48c20
Successfully built 6d67c0d48c20
Successfully tagged baidu.com/test-helloworld:1.0.0

 

會發現我們Dockerfile檔案內容一共四行,執行程序也是Step 1/2/3/4四步,這就知道了Dockerfile內容的行數決定了Step的步驟數,

那么每一步都代表啥呢?

其實每一步都會為我們創建一個臨時容器,這樣做的好處是如果下次再構建這個Dockerfile的時候,直接從cache里讀出已有的容器,不重復創建容器,這樣大大節省了構建時間,也不會浪費資源重復創建容器,比如如下:

FROM tomcat:latest
MAINTAINER baidu.com
WORKDIR /usr/local/tomcat/webapps
ADD helloworld ./helloworld
ADD helloworld ./helloworld2

 

啥也沒動,就是多部署一份helloworld且在容器內部改名為helloworld2,接下來看執行程序

Step 1/5 : FROM tomcat:latest
 ---> 1b6b1fe7261e
Step 2/5 : MAINTAINER baidu.com
 ---> Using cache
 ---> 5d0da6398f7e
Step 3/5 : WORKDIR /usr/local/tomcat/webapps
 ---> Using cache
 ---> 9bf9672cd60e
Step 4/5 : ADD helloworld ./helloworld
 ---> Using cache
 ---> 6d67c0d48c20
Step 5/5 : ADD helloworld ./helloworld2
 ---> 4e5ffc24522f
Successfully built 4e5ffc24522f
Successfully tagged baidu.com/test-helloworld:1.0.1

 

首先可以發現如下:

1.Step變成了5步,

2.前四步驟用了快取Using Cache,并沒有重復創建容器,Step 1 沒有Using Cache是因為它是從本地倉庫直接拉取了tomcat:latest當作基礎鏡像,run的時候會創建容器,

3.第五步重新創建了臨時容器,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/182415.html

標籤:Java

上一篇:【報錯】匯入專案后報錯:Target runtime Apache Tomcat v7.0 is not defined.

下一篇:Spring Cloud 和 Dubbo 哪個會被淘汰?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more