標籤: 租車

  • 手動造輪子——基於.NetCore的RPC框架DotNetCoreRpc

    手動造輪子——基於.NetCore的RPC框架DotNetCoreRpc

    前言

        一直以來對內部服務間使用RPC的方式調用都比較贊同,因為內部間沒有這麼多限制,最簡單明了的方式就是最合適的方式。個人比較喜歡類似Dubbo的那種使用方式,採用和本地方法相同的方式,把接口層獨立出來作為服務契約,為服務端提供服務,客戶端也通過此契約調用服務。.Net平台上類似Dubbo這種相對比較完善的RPC框架還是比較少的,GRPC確實是一款非常優秀的RPC框架,能跨語言調用,但是每次還得編寫proto文件,個人感覺還是比較麻煩的。如今服務拆分,微服務架構比較盛行的潮流下,一個簡單實用的RPC框架確實可以提升很多開發效率。

    簡介

        隨着.Net Core逐漸成熟穩定,為我一直以來想實現的這個目標提供了便利的方式。於是利用閑暇時間本人手寫了一套基於Asp.Net Core的RPC框架,算是實現了一個自己的小目標。大致的實現方式,Server端依賴Asp.Net Core,採用的是中間件的方式攔截處理請求比較方便。Client端可以是任何可承載.Net Core的宿主程序。通信方式是HTTP協議,使用的是HttpClientFactory。至於為什麼使用HttpClientFactory,因為HttpClientFactory可以更輕鬆的實現服務發現,而且可以很好的集成Polly,很方便的實現,超時重試,熔斷降級這些,給開發過程中提供了很多便利。由於本人能力有限,基於這些便利,站在巨人的肩膀上,簡單的實現了一個RPC框架,項目託管在GitHub上https://github.com/softlgl/DotNetCoreRpc有興趣的可以自行查閱。

    開發環境

    • Visual Studio 2019
    • .Net Standard 2.1
    • Asp.Net Core 3.1.x

    使用方式

        打開Visual Studio先新建一個RPC契約接口層,這裏我起的名字叫IRpcService。然後新建一個Client層(可以是任何可承載.Net Core的宿主程序)叫ClientDemo,然後建立一個Server層(必須是Asp.Net Core項目)叫WebDemo,文末附本文Demo連接,建完這些之後項目結構如下:

    Client端配置

    Client端引入DotNetCoreRpc.Client包,並引入自定義的契約接口層

    <PackageReference Include="DotNetCoreRpc.Client" Version="1.0.2" />
    

    然後可以愉快的編碼了,大致編碼如下

    class Program
    {
        static void Main(string[] args)
        {
            IServiceCollection services = new ServiceCollection();
            //*註冊DotNetCoreRpcClient核心服務
            services.AddDotNetCoreRpcClient()
            //*通信是基於HTTP的,內部使用的HttpClientFactory,自行註冊即可
            .AddHttpClient("WebDemo", client => { client.BaseAddress = new Uri("http://localhost:13285/"); });
    
            IServiceProvider serviceProvider = services.BuildServiceProvider();
            //*獲取RpcClient使用這個類創建具體服務代理對象
            RpcClient rpcClient = serviceProvider.GetRequiredService<RpcClient>();
    
            //IPersonService是我引入的服務包interface,需要提供ServiceName,即AddHttpClient的名稱
            IPersonService personService = rpcClient.CreateClient<IPersonService>("WebDemo");
    
            PersonDto personDto = new PersonDto
            {
                Id = 1,
                Name = "yi念之間",
                Address = "中國",
                BirthDay = new DateTime(2000,12,12),
                IsMarried = true,
                Tel = 88888888888
            };
    
            bool addFlag = personService.Add(personDto);
            Console.WriteLine($"添加結果=[{addFlag}]");
    
            var person = personService.Get(personDto.Id);
            Console.WriteLine($"獲取person結果=[{person.ToJson()}]");
    
            var persons = personService.GetAll();
            Console.WriteLine($"獲取persons結果=[{persons.ToList().ToJson()}]");
    
            personService.Delete(person.Id);
            Console.WriteLine($"刪除完成");
    
            Console.ReadLine();
        }
    }
    

    到這裏Client端的代碼就編寫完成了

    Server端配置

    Client端引入DotNetCoreRpc.Client包,並引入自定義的契約接口層

    <PackageReference Include="DotNetCoreRpc.Server" Version="1.0.2" />
    

    然後編寫契約接口實現類,比如我的叫PersonService

    //實現契約接口IPersonService
    public class PersonService:IPersonService
    {
        private readonly ConcurrentDictionary<int, PersonDto> persons = new ConcurrentDictionary<int, PersonDto>();
        public bool Add(PersonDto person)
        {
            return persons.TryAdd(person.Id, person);
        }
    
        public void Delete(int id)
        {
            persons.Remove(id,out PersonDto person);
        }
    
        //自定義Filter
        [CacheFilter(CacheTime = 500)]
        public PersonDto Get(int id)
        {
            return persons.GetValueOrDefault(id);
        }
    
        //自定義Filter
        [CacheFilter(CacheTime = 300)]
        public IEnumerable<PersonDto> GetAll()
        {
            foreach (var item in persons)
            {
                yield return item.Value;
            }
        }
    }
    

    通過上面的代碼可以看出,我自定義了Filter,這裏的Filter並非Asp.Net Core框架定義的Filter,而是DotNetCoreRpc框架定義的Filter,自定義Filter的方式如下

    //*要繼承自抽象類RpcFilterAttribute
    public class CacheFilterAttribute: RpcFilterAttribute
    {
        public int CacheTime { get; set; }
    
        //*支持屬性注入,可以是public或者private
        //*這裏的FromServices並非Asp.Net Core命名空間下的,而是來自DotNetCoreRpc.Core命名空間
        [FromServices]
        private RedisConfigOptions RedisConfig { get; set; }
    
        [FromServices]
        public ILogger<CacheFilterAttribute> Logger { get; set; }
    
        public override async Task InvokeAsync(RpcContext context, RpcRequestDelegate next)
        {
            Logger.LogInformation($"CacheFilterAttribute Begin,CacheTime=[{CacheTime}],Class=[{context.TargetType.FullName}],Method=[{context.Method.Name}],Params=[{JsonConvert.SerializeObject(context.Parameters)}]");
            await next(context);
            Logger.LogInformation($"CacheFilterAttribute End,ReturnValue=[{JsonConvert.SerializeObject(context.ReturnValue)}]");
        }
    }
    

    以上代碼基本上完成了對服務端業務代碼的操作,接下來我們來看如何在Asp.Net Core中配置使用DotNetCoreRpc。打開Startup,配置如下代碼既可

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IPersonService, PersonService>()
            .AddSingleton(new RedisConfigOptions { Address = "127.0.0.1:6379", Db = 10 })
            //*註冊DotNetCoreRpcServer
            .AddDotNetCoreRpcServer(options => {
                //*確保添加的契約服務接口事先已經被註冊到DI容器中
    
                //添加契約接口
                //options.AddService<IPersonService>();
    
                //或添加契約接口名稱以xxx為結尾的
                //options.AddService("*Service");
    
                //或添加具體名稱為xxx的契約接口
                //options.AddService("IPersonService");
    
                //或掃描具體命名空間下的契約接口
                options.AddNameSpace("IRpcService");
    
                //可以添加全局過濾器,實現方式和CacheFilterAttribute一致
                options.AddFilter<LoggerFilterAttribute>();
            });
        }
    
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            //這一堆可以不要+1
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
    
            //添加DotNetCoreRpc中間件既可
            app.UseDotNetCoreRpc();
    
            //這一堆可以不要+2
            app.UseRouting();
    
            //這一堆可以不要+3
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Server Start!");
                });
            });
        }
    }
    

    以上就是Server端簡單的使用和配置,是不是感覺非常的Easy。附上可運行的Demo地址,具體編碼可查看Demo.

    總結

        能自己實現一套RPC框架是我近期以來的一個願望,現在可以說實現了。雖然看起來沒這麼高大上,但是整體還是符合RPC的思想。主要還是想自身實地的實踐一下,順便也希望能給大家提供一些簡單的思路。不是說我說得一定是對的,我講得可能很多是不對的,但是我說的東西都是我自身的體驗和思考,也許能給你帶來一秒鐘、半秒鐘的思考,亦或是哪怕你覺得我哪一句話說的有點道理,能引發你內心的感觸,這就是我做這件事的意義。最後,歡迎大家評論區或本項目GitHub下批評指導。

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

    【其他文章推薦】

    ※別再煩惱如何寫文案,掌握八大原則!

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

    ※超省錢租車方案

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

    網頁設計最專業,超強功能平台可客製化

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

  • 沒有國產主機,怎麼開發:交叉編譯和QEMU虛擬機

    沒有國產主機,怎麼開發:交叉編譯和QEMU虛擬機

    1. 背景

    近期國產化的趨勢越來越濃,包括國產操作系統、國產CPU等。時隔十多年,QQ for Linux也更新了。做為軟件開發人員,“有幸”也需要適配國產化。至於國產化的意義等就不在此討論。

    本文提到的國產主機主要是指使用國產CPU和操作系統的計算機,比如:操作系統是銀河麒麟,CPU是飛騰FT2000。如果需要做適配開發,起碼需要一台對應的主機吧。據說在國產化早期,有錢都難買到機器,需要特殊渠道申請購買。不過,現在購買還是比較方便的。

    通過客戶提供的正規正統的廠家詢價,着實嚇一跳,一台居然要一萬多!!而同等性能配置的windows-x86普通台式主機,才兩三千塊左右,相差有點大呀。本着能省就省的原則,上萬能的某寶看能不能淘一個。真得感謝馬爸爸和深圳華強北,5千多塊,突然感覺肉沒那麼痛了。

    其實完全可以理解,國產的批量肯定很小很小,價格必然是高的。對於不專門開發“國產軟件”的公司來說,買一台使用率比較低的機器不太值得。後面將介紹在沒有國產主機情況下,進行軟件開發的兩種替代方法:交叉編譯和QEMU虛擬機。

    2. 銀河麒麟是什麼

    銀河麒麟操作系統有服務器版本和桌面版本,本文使用的是桌面版本。具體細節看官方的介紹即可,就不做搬運工了。官方說的自主研發、安全可控都不是我們所關心的,我們只需要關心它的內核是什麼,會不會如網上所說根本就是個Ubutun,改個皮膚而已?!。

    先用VMware安裝個虛擬機試試吧,網上找了一個只有X86架構的鏡像包Kylin-4.0.2-desktop-sp2_Community-20171127-x86_64.iso,安裝過程略過,使用命令“uname -a”查一下。

    Linux wrgz-Lenovo 4.11.0-14-generic #20~16.04.1kord0k1-Ubuntu SMP Wed Oct 18 00:56:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
    

    看到Ubuntu就放心了,就當它是個Ubuntu Linux就行了。

    3. 飛騰FT2000又是什麼

    通俗點講它就是個CPU,再看看飛騰的官網上的描述。FT-2000系列芯片是基於飛騰片上并行系統(PSoC)體繫結構設計的通用微處理器,兼容ARMv8指令集,兼容支持ARM64和ARM32兩種執行模式。哦嚯,划個重點,簡單點看它就是一個ARMv8的64位CPU。

    划個不考試的重點:對於應用軟件開發者,簡單理解為是在ARMv8架構上的Ubuntu Linux上進行開發軟件;對於普通辦公者,則理解為是仿Windows的Linux系統。

    4. 交叉編譯

    本文提到的軟件開發,是使用C/C++開發無界面的應用軟件,實際上開發和測試都有是可以在Ubuntu上進行。但發布軟件則需要真機編譯或者交叉編譯才能運行。

    很幸運,在上飛騰官網時,發現了飛騰FT2000的技術文檔FT-2000+64Sv1.1.pdf,裏面有介紹到交叉編譯環境。

    • 安裝Ubuntu16.04(可安裝在虛擬機上或 X86電腦裸機上)
    • 安裝成功后,虛擬機 apt 源修改 修改/etc/apt/source.list 內容為如下:
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates main restricted
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial universe
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates universe
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial multiverse
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates multiverse
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-backports main restricted universe > multiverse
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security main restricted
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security universe
    deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security multiverse
    
    • 運行 apt-get update,再運行apt-get install gcc-aarch64-linux-gnu安裝
    • 使用命令aarch64-linux-gnu-gcc –v可以看到gcc版本號為gcc version 5.4.0 20160609

    有了交叉編譯器,編譯是很輕鬆的事。經後續測試,交叉編譯出來的程序,可以在國產真機上運行。

    5. QEMU虛擬機是什麼

    我們經常使用的虛擬機軟件是VMware,擺着這麼好的不用,為什麼選擇QEMU呢。這得從他們的區別說起。

    VMware重點於在一個硬件平台下運行多個操作系統,虛擬硬件平台與宿主硬件架構一致,也就是說虛擬機程序中的指令一般就是宿主CPU指令集,可以直接執行,因此一般速度上也就比較快。

    QEMU的特點是可以虛擬不同的硬件平台架構,比如在X86機器上虛擬出ARM架構的機器。許多基於ARM指令集的Android手機模擬器是基於Qemu的,很適合無真機情況下進行Android開發。當然執行ARM指令,需要轉換成X86指令才能在宿主機器上運行,這樣速度一般會慢點。

    由於本文提到的國產主機就是ARM架構的,VMware並不適用,而QEMU則符合要求。還有一個原因是QEMU支持Windows,只需要一個安裝包,安裝過程簡單,太香了。

    6. QEMU安裝銀河麒麟操作系統

    無獨有偶,鯤鵬處理器也是ARMv8指令集,在華為官網看到詳細的安裝過程,安裝細節可參考https://www.huaweicloud.com/kunpeng/software/qemu.html。

    下面只針對一些重點關注點做些說明。

    • 需要下載一個Arm64架構的麒麟桌面操作系統鏡像包,名字類似Kylin-4.0.2-desktop-sp3-xxxxxxx-arm64.iso。之所以重點提這點,是因為這種鏡像包在網上很難找。有想到用Arm64架構的Ubuntu鏡像包代替,才發現原來官方並沒有提供ARM桌面版的鏡像包(有ARM服務器版)。
    • 原來華為提供的安裝參數有些問題,包括網絡、鼠標、鍵盤參數。這些參數配置不對,會直接影響使用。

    QEMU有一個不太人性化的特點,就是沒有提供類似VMware的界面操作,只能通過命令操作,參數還特別多,網上的資料不多,官方文檔都有是英文的。下面給出三個重要的QEMU命令:創建、安裝、啟動。

    創建
    這個步驟就是創建一個預分配一個大文件,做為虛擬機的磁盤,我比較任性地分配了40G。

    c:\qemu\qemu-img.exe create D:\qemu\vm\kylin\hdd01.img 40G
    

    安裝

    c:\qemu\qemu-system-aarch64.exe -m 4096 -cpu cortex-a72 -smp 2,cores=2,threads=1,sockets=1 -M virt -bios D:\qemu\bios\QEMU_EFI.fd -net nic,model=pcnet -device nec-usb-xhci -device usb-kbd -device usb-mouse -device VGA -drive if=none,file=D:\software\kylin\Kylin-4.0.2-desktop-sp3-19122616.Z1-arm64.iso,id=cdrom,media=cdrom -device virtio-scsi-device -device scsi-cd,drive=cdrom -drive if=none,file=D:\qemu\vm\kylin\hdd01.img,id=hd0 -device virtio-blk-device,drive=hd0
    

    啟動

    c:\qemu\qemu-system-aarch64.exe -m 4096 -cpu cortex-a72 -smp 2,cores=2,threads=1,sockets=1 -M virt -bios D:\qemu\bios\QEMU_EFI.fd -net nic -net tap,ifname=tap0 -device nec-usb-xhci -device usb-kbd -device usb-mouse -device VGA -device virtio-scsi-device -drive if=none,file=D:\qemu\vm\kylin\hdd01.img,id=hd0 -device virtio-blk-device,drive=hd0
    

    安裝和啟動的命令參數差不多,統一說明它們的含義:

    參數 說明
    qemu-system-aarch64.exe 二進制文件,提供模擬aarch64架構的虛擬機進程
    -m 2048 分配2048MB內存
    -M virt 模擬成什麼服務器,我們一般選擇virt就可以了,他會自動選擇最高版本的virt
    -cpu cortex-a72 模擬成什麼CPU,其中cortex-a53\a57\a72都是ARMv8指令集的
    -smp 2,cores=2,threads=1,sockets=1 2個vCPU,這2個vCPU由qemu模擬出的一個插槽(socket)中的2個核心,每個核心支持一個超線程構成
    -bios xxx 指定bios bin所在的路徑
    -device xxx 添加一個設備,參數可重複
    -drive 添加一個驅動器,參數可重複
    -net 添加網絡設備

    QEMU虛擬機怎麼連網
    在Windows上使用qemu虛擬機,使虛擬機能連網,配置方法如下:

    • 在Windows主機上安裝TAP網卡驅動:可下載openvpn客戶端軟件,只安裝其中的TAP驅動;在網絡連接中,會看到一個新的虛擬網卡,屬性類似於TAP-Windows Adapter V9,將其名稱修改為tap0
    • 將虛擬網卡和Windows上真實網卡橋接:選中這兩塊網卡,右鍵,橋接。此時,Windows主機將不能連接互聯網,需要在網橋上配置IP地址和域名等信息,才能使Windows主機連接互聯網。
    • QEMU參數配置:在虛擬機啟動命令行添加以下參數–net nic -net tap,ifname=tap0;tap0為的虛擬網卡名。

    7. 總結

    國產操作系統的使用體驗已經好了很多,輕度辦公室還是可行的,但想替換Windows,太難了。
    QEMU可以虛擬不同的硬件平台架構,是個不錯的虛擬機軟件,而且開源,但在使用體驗方面還是差了一些。

    歡迎關注我的公眾號【林哥哥的編程札記】,謝謝!

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

    【其他文章推薦】

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

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

    ※回頭車貨運收費標準

    ※別再煩惱如何寫文案,掌握八大原則!

    ※超省錢租車方案

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

  • 寫了個全局變量的bug,被同事們打臉!!!

    寫了個全局變量的bug,被同事們打臉!!!

    話說棧長前陣子寫了一個功能,測試 0 bug 就上線了,上線后也運行好好的,好多天都沒有人反饋bug,超爽。。

    不出問題還好,出問題就是大問題。。

    最近有個客戶反饋某些數據混亂問題,看代碼死活看不出什麼問題,很詭異,再仔細看代碼,原來是一個全局變量的問題,導致在併發情況下出現了線程不安全的問題,事後被同事們打臉!!!

    慎用全局變量,我在公司一直在強調,沒想到這麼低級的問題居然發生在自己身上,說起來真的慚愧啊。。

    最開始使用的是 Spring 注入對象的方式:

    @Autowired
    private Object object;
    

    因為 Spring 默認是單例,所以這樣寫是沒有問題的,後來隨着業務的發展,需要多個不同的業務實例,我改成了這種方式:

    @Setter
    private Object object;
    

    這個 @Setter 是 Lombok 的註解,用來生成 setters 方法,現在想起來,真是低級啊,同時操作的情況下,這個對象肯定會出現覆蓋的情況,從而導致上面說的問題。

    寫了一個這麼低級bug,我也不怕不好意思發出來,大家都謹記一下吧。

    另外,我再總結幾個慎用全局變量的場景:

    1、SimpleDateFormat

    SimpleDateFormat 禁止定義成 static 變量或者全局共享變量,因為它是線程不安全的,都被寫進阿里巴巴的《Java開發手冊》里了:

    為什麼說 SimpleDateFormat 不是線程安全的呢?

    來看下它的 format 方法源碼:

    可以看到 calendar 變量居然也是全局變量,多線程情況下就會存在設置臟變量的情況。

    所以,如果要用 SimpleDateFormat,就在每次用的時候都創建一個 SimpleDateFormat 對象,做到線程間隔離。

    2、資源連接

    資源連接包括數據庫連接、FTP連接、Redis連接等,這種也要慎用全局變量,一量使用全局變量,就會遇到以下問題:

    1)關閉連接的時候,就可能把別人正在操作的連接給關了,導致其他線程的業務中斷;

    2)因為是全局變量,創建的時候可能會創建多個實例,在關閉連接的時候,就可能只關閉了一個對象的連接,造成其他連接沒有被關閉,最後導致連接耗光系統不可用;

    3、数字運算

    這也是個很經典的問題了,如果要用多線程對一個数字進行累加等其他運算處理,千萬不要用全局基礎類型的變量,如下所示:

    private long count;
    

    多線程情況下,某個線程獲取到的值可能已經被其他線程修改了,最後得到的值就不準確了。

    當然,上面的示例可以通過加鎖的方式來解決,也可以使用全局的原子類(java.util.concurrent.atomic.Atom*)進行處理,比如:

    private AtomicInteger count = new AtomicInteger();
    

    注意,這種原子類使用全局變量就沒有線程安全的問題,它使用了 CAS 算法保證了數據一致性。

    不過,阿里推薦使用LongAdder,因為性能更好:

    java.util.concurrent.atomic.LongAdder

    4、全局session

    來看下面的例子:

    @Autowired
    protected HttpSession session;
    

    全局注入一個 Session 對象,在 Spring 中,這樣全局注入使用上面是默認沒問題的,包括 request, response 對象,都可以通過全局注入來獲取。

    這樣會存在線程安全性嗎?

    不會!

    使用這種方式,當 Bean 初始化時,Spring 並沒有注入真實對象,而是注入了一個代理對象,真正使用的時候通過該代理對象獲取真正的對象。

    並且,在注入此類對象時,Spring使用了線程局部變量(ThreadLocal),這就保證了 request/response/session 對象的線程安全性了。

    具體就不展開了,詳細的介紹及測試大家可以點擊這個鏈接查看這篇文章。

    既然是線程安全,但也得小心,如果我在方法中主動使 session 對象失效並重建了:

    session.invalidate();
    session = request.getSession();
    

    這樣,session對象就變成了真實對象了,不再是代理對象,就變成了文章最開始的時候我說的那種多線程安全問題了,如果線上出現 session 會話混亂,用戶 A 就可能看到用戶 B 的數據,你想想可不可怕?

    所以,即使可以這樣使用,也得千萬小心謹慎,最好是在方法級別使用這些對象。

    總結

    今天,棧長總結了一下我是怎麼寫出這個全局變量的低級 bug,也總結了下慎用全局變量的 4 種情況,相信大家多多少都遇到過類似的問題,希望能幫助大家少踩坑。

    全局變量雖好,但我們也得謹慎使用啊,一定要考慮是否引起多線程安全問題,不然會引起重大問題。

    你還遇到過哪些全局變量的問題,歡迎留言分享哦!

    推薦去我的博客閱讀更多:

    1.Java JVM、集合、多線程、新特性系列教程

    2.Spring MVC、Spring Boot、Spring Cloud 系列教程

    3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

    4.Java、後端、架構、阿里巴巴等大廠最新面試題

    覺得不錯,別忘了點贊+轉發哦!

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

    【其他文章推薦】

    ※超省錢租車方案

    ※別再煩惱如何寫文案,掌握八大原則!

    ※回頭車貨運收費標準

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

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

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

  • 南非克魯格公園防疫封鎖 動物佔領度假屋

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

    南非為防止武漢肺炎(COVID-19)擴大進行各階段封鎖,知名的克魯格國家公園住宿小屋因長時間無人入住,部分屋舍遭動物佔領與破壞,園方已展開維修,準備重新逐步開放。

    武漢肺炎爆發後,南非自3月26日進入最嚴格的第5級全國封鎖,幾個月來因疫情變化逐漸開放,8月18日起改善第2級,國家公園開放旅遊觀光。

    新聞網站「時報即時消息」(TimesLIVE)今(31日)引述南非國家公園管理處執行長姆克特尼(Fundisile Mketeni)表示,克魯格國家公園(Kruger National Park)準備重新開放面臨許多挑戰,特別是清潔與維修工作。疫情封鎖期間,部分住宿小屋被靈長類動物、松鼠與蝙蝠佔領和破壞。

    姆克特尼指出,已迅速維修,預計9月份會有旅遊高峰。

    國際新聞
    南非
    防疫
    國家公園

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

    【其他文章推薦】

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

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

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

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

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

    ※超省錢租車方案

  • 北極圈驚見50公尺深「天坑」 專家解謎:甲烷噴炸

    北極圈驚見50公尺深「天坑」 專家解謎:甲烷噴炸

    摘錄自2020年9月1日自由時報報導

    綜合外媒報導,俄羅斯北極圈內凍原帶的夏天近年異常炎熱,導致不斷發生大規模爆炸,近日突然發生一起爆炸,導致炸出一個深約50公尺的超級大洞,當地居民議論紛紛。

    俄羅斯石油天然氣研究所(Russian Oil and Gas Research Institute)教授波哥亞夫蘭斯基(Vasily Bogoyavlensky)表示,爆炸可能是永凍土層慢慢融化後,原本冰封在泥土縫隙中的沼氣不斷釋放、噴發而成,其所引起的爆炸的巨大威力將土壤及冰塊拋到數百公尺外。但哥亞夫蘭斯基也補充,鑽探天然氣也有可能會引發爆炸。

    氣候變遷
    國際新聞
    俄羅斯
    永凍土
    凍原
    北極圈
    甲烷

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

    【其他文章推薦】

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

    ※別再煩惱如何寫文案,掌握八大原則!

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

    ※超省錢租車方案

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

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

  • 全球冰川湖增53% 冰川融化形成湖泊水量增 恐釀洪災

    摘錄自2020年9月1日聯合報報導

    由於氣候暖化導致冰川融化,自1990年起,全球冰川湖的數量已增加53%。影像顯示,冰川湖數量在1990年至2018年間增長53%,使湖泊覆蓋地球的面積擴大約51%。根據調查,有1萬4394個冰湖散布在近9000平方公里的地球表面上。

    科學家分析來自NASA和谷歌地球引擎的衛星影像數據,評估冰川融化後所形成的湖泊如何受到全球暖化和其他過程影響。根據這些數據,研究人員估計,全球冰川湖水量在1990年至2018年間增加48%,目前總計約達156.5立方公里。

    對於世界上許多最貧窮的人來說,冰川湖是重要的淡水資源,尤其是在亞洲山區和南美部分地區。但大量冰融水注入湖中會導致下游地區面臨洪水威脅,能摧毀村莊、沖刷道路、破壞管線和其他基礎設施。

    氣候變遷
    國際新聞
    全球
    冰川融化
    全球暖化
    洪水

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

    【其他文章推薦】

    ※別再煩惱如何寫文案,掌握八大原則!

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

    ※超省錢租車方案

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

    網頁設計最專業,超強功能平台可客製化

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

  • 日貨輪觸礁漏油毀生態 模里西斯擬求償9.9億

    摘錄自2020年9月1日自由時報報導

    日本大型貨輪「若潮號」(WAKASHIO)7月在模里西斯近海觸礁,超過千噸燃油外洩造成當地生態浩劫,模里西斯政府計畫求償13.4億模里西斯盧比(約新台幣9.95億元)。另外,協助清理漏油的拖船昨晚(31日)撞上駁船,造成2死2失蹤。

    綜合外媒報導,日本商船三井集團營運的巴拿馬籍大型散貨輪「若潮號」7月25日觸礁時,載有約3800噸燃油,據悉,有1000多噸燃油外洩海上,被污染的沿海地區已禁止捕魚,模里西斯政府也在8月7日宣布進入環境緊急狀態,擔心瀕物種恐受到影響。

    根據模里西斯政府文件顯示的擬議計畫,當局將向日方求償13.4億模里西斯盧比,這筆錢將用來支持受到漏油影響的當地漁民社區,其中12億盧比用於建造100艘漁船、970萬盧比用於為475名漁民和60名船長提供培訓。

    污染治理
    國際新聞
    模里西斯
    燃油外洩
    漏油事件
    觸礁

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

    【其他文章推薦】

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

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

    ※回頭車貨運收費標準

    ※別再煩惱如何寫文案,掌握八大原則!

    ※超省錢租車方案

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

  • 深圳強制垃圾分類 罰款最高216萬

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

    鄰近香港的中國大陸深圳市昨(1日)起強制實施垃圾分類,違反的話最高罰款人民幣50萬元(新台幣216萬元)。

    深圳新聞網今(2日)報導,深圳昨天起實施「深圳市生活垃圾分類管理條例」,羅湖區銀龍花園物業負責人收到首張整改通知書,原因是社區沒有設置分類投放點,且大件垃圾未及時清運。

    報導表示,深圳對相關處罰分為個人和單位兩類,其中對運輸類垃圾的收運單位處5萬元以上50萬元以下罰款;個人的生活垃圾處50元罰款,情節嚴重的罰200元。

    2019年起,大陸一些城市開始推動垃圾分類,以改善環境,提升城市生態水平。

    污染治理
    國際新聞
    中國
    垃圾分類

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

    【其他文章推薦】

    ※超省錢租車方案

    ※別再煩惱如何寫文案,掌握八大原則!

    ※回頭車貨運收費標準

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

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

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

  • 2016全年轎車銷量前十齣爐 國產轎車榮譽上榜!

    2016全年轎車銷量前十齣爐 國產轎車榮譽上榜!

    第四名:大眾捷達全年銷量:348,437輛捷達在中國還真是“常青樹”般的存在,一直以來銷量居高不下,而且相對於桑塔納更受駕校、政府機關以及企業所喜愛,這讓它獲得了不少的企業訂單。而選擇它的原因就是其多年以來良好的口碑以及不過時的外觀。

    前言

    在學校中,學生們最為重視的就是考試成績了,這反映的就是他們自己的素質。而對於汽車來說,全年銷量就是最終成績了,那麼在2016中有哪些車型賣得最為火爆呢?

    第十名:吉利帝豪EC7

    全年銷量:223,781輛

    相信熟悉吉利帝豪的肯定知道它為什麼能熱火那麼多年了,不過也需要換代了不是嗎?

    第九名:現代朗動

    全年銷量:253,804輛

    在伊蘭特、悅動、朗動、領動“四代同堂”的情況 ,朗動的銷量在12月還是能達到3萬級別,證明了朗動的競爭實力依然不可忽視。

    第八名:大眾新桑塔納

    全年銷量:282,815輛

    新桑塔納在顏值上已經不會以前那種很low的感覺,加上親民的價格以及不俗的耐用度,成為第八是毫無意外的,但是令人費解的是為什麼會落後同門的捷達那麼多呢?

    第七名:福特福睿斯

    全年銷量:296,867輛

    福特終於懂得中國人的消費心理,大空間低價格才是中國人需要的,這款價格更低的中國特供車要比正統軍——福克斯要高,所以車型在外國賣得再好,也是先要適合國人的需求。

    第六名:豐田卡羅拉

    全年銷量:307,360輛

    卡羅拉的存在說明了中國喜愛的還是中庸,平淡的外觀內飾以及動力表現是卡羅拉的性能特點,但大空間以及低油耗、低故障率卻是我們最注重的。它的銷量一直都不錯,相對於外觀年輕激進的雷凌它的迎合面更廣,所以它比雷凌高銷量是正常的事。

    第五名:大眾速騰

    全年銷量:341,331輛

    在銷量前十的車型中,平均售價是比較高的一款車型。那句戲謔“這車比較高級”雖然搞笑,但也證明了速騰又或者說是德系車在我國消費者心中的形象,事實上它渦輪增壓+雙離合車型性能表現也是不錯。

    第四名:大眾捷達

    全年銷量:348,437輛

    捷達在中國還真是“常青樹”般的存在,一直以來銷量居高不下,而且相對於桑塔納更受駕校、政府機關以及企業所喜愛,這讓它獲得了不少的企業訂單。而選擇它的原因就是其多年以來良好的口碑以及不過時的外觀。

    第三名:日產軒逸

    全年銷量:367,979輛

    軒逸是這次榜單的正統生力軍,來自日本的它和我們需求有着不少相似的地方。輕巧的駕駛風格、低油耗、優秀的乘坐空間以及舒適的乘坐體驗使得它非常適合中國人的口味。而且相對於卡羅拉,內飾也更為時尚好看,成為這個榜單的前三可謂是實至名歸。

    第二名:全新別克英朗

    全年銷量:370,370輛

    再次說明了明白中國人需求就能打造一輛熱銷的車型,別克上有威朗下有英朗,而根據國人喜好打造的全新英朗也是如此。夠用的空間加上美系車擅長的NVH,使得它有着超越該價位價值的感覺。

    第一名:大眾朗逸

    全年銷量:478,699輛

    這才是中國特供車的高手,藉著速騰的威名,使用成熟的平台降低了研發成本,從而降低了車價。和速騰差不多的外觀,但是價格比起速騰低了不少,所以第一的寶座非它莫屬,全年銷量比起第二的全新英朗要高出十萬輛。

    編者總結:

    這個榜單中除朗動這已經換代的車型,年銷量都有着不同程度的提升,其中增幅最大的就是全新別克英朗以及福特福睿斯,加上同樣增幅不少的大眾朗逸,證明了我國需要的就是價格親民,性能夠用以及故障率低的車型。這些“中國特供車”才能那麼暢銷,所以“中國特供”絕非是一個貶義詞。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

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

    ※別再煩惱如何寫文案,掌握八大原則!

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

    ※超省錢租車方案

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

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

  • 全新國貨7座車型上市 寶駿730和五菱表示慌了?

    全新國貨7座車型上市 寶駿730和五菱表示慌了?

    內飾造型不錯,看着挺討人喜歡的,中控台部分區域採用了皮革包裹,手感很好。8英寸中控屏幕起到了畫龍點睛的效果。座椅寬大柔軟,舒適性不錯,,車內空間較大,甚至可以蹺二郎腿。作為MpV,第三排的空間尤為重要,M70的第三排空間表現符合這個級別的標準。

    昌河的小麵包在國內絕對是家喻戶曉了,小時候看到那麼簡陋的麵包車依然會覺得那是好車,不過隨着國內汽車市場的發展,這類的MpV也越來越精緻化了。看到宏光和寶駿730大紅大紫,作為老牌选手昌河自然也坐不住了。

    所以,昌河M70就在今天正式上市了,M70作為昌河旗下的全新MpV,產品實力到底如何呢?別急,我們今天就好好好分析一下昌河M70。

    根據配置不同新車共有五款車型供大家選擇,最大程度的滿足消費者的用車需求。

    M70的車身尺寸為4720*1770*1800/1828mm,軸距為2810mm,其中高度之所以有些許差異是因為中高配車型將會配備車頂行李架的緣故。M70旗下還有一款車型,叫M50,M70的定位要明顯高於M50,配置也更豐富,空間也夠大,所以M70的定位是既宜商又宜家。

    因為M70是昌河旗下的最新車型,所以從外觀設計上M70並沒有很明顯的短板,M70的前臉設計的很大氣,前進氣格柵採用了較多的鍍鉻處理,三根較寬的鍍鉻裝飾橫條與前大燈組相連,這樣的設計會顯得車頭看起來比較寬,感覺很有力量感。所以M70前臉看起來比較大氣。

    車身側面看起來比較飽滿,硬朗。

    尾部造型很簡單,沒有過多的裝飾,簡潔的線條處理讓M70的尾部看起來比較素氣,讓人有很清爽的感覺。當然有的消費者覺得這樣的設計看起來太過於簡單,沒有檔次,不對自己的胃口。所以說,眾口難調么!外觀這個東西的評判還是有些感性的。

    整體來看,M70採用了稜角分明的設計,線條犀利,造型硬朗,以至於這台MpV甚至會給我一種SUV的感覺。

    內飾造型不錯,看着挺討人喜歡的,中控台部分區域採用了皮革包裹,手感很好。8英寸中控屏幕起到了畫龍點睛的效果。

    座椅寬大柔軟,舒適性不錯,,車內空間較大,甚至可以蹺二郎腿。作為MpV,第三排的空間尤為重要,M70的第三排空間表現符合這個級別的標準。

    M70搭載1.5L自然吸氣發動機,最大功率為113馬力,峰值扭矩為150牛·米,變速箱為5擋手動。M70的懸架很有意思,比如它的低配車型的后懸架為鋼板彈簧非獨立懸架,中高配車型為螺旋彈簧非獨立懸架。所以說,不管是拉貨還在坐人,M70不同的懸架組合可以滿足你不同的需求。

    我們還是最推薦頂配的M70,相對來說它的性價比最高了,像無鑰匙啟動/進入系統,天窗,鋁合金輪圈,真皮方向盤,前/后駐車雷達,倒車視頻影像,仿皮座椅,前排座椅加熱,GpS導航,中控大屏,藍牙,日間行車燈,後座出風口等都有配備。但是即使是頂配的M70,也沒有ESp,這點讓人不太滿意。

    競爭對手

    五菱宏光

    指導價:4.18-6.98萬

    寶駿730

    指導價:6.08-9.28萬

    五菱宏光被譽為神車,730也是這個級別的重量級选手,M70想要超過它們確實比較難,但是M70可以依靠自己更豐富的配置來吸引一部分客戶,畢竟M70的性價比還是不錯的。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※別再煩惱如何寫文案,掌握八大原則!

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

    ※超省錢租車方案

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

    網頁設計最專業,超強功能平台可客製化

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!