基於 abp vNext 和 .NET Core 開發博客項目 – 定時任務最佳實戰(二)_貨運

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

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

系列文章

  1. 基於 abp vNext 和 .NET Core 開發博客項目 – 使用 abp cli 搭建項目
  2. 基於 abp vNext 和 .NET Core 開發博客項目 – 給項目瘦身,讓它跑起來
  3. 基於 abp vNext 和 .NET Core 開發博客項目 – 完善與美化,Swagger登場
  4. 基於 abp vNext 和 .NET Core 開發博客項目 – 數據訪問和代碼優先
  5. 基於 abp vNext 和 .NET Core 開發博客項目 – 自定義倉儲之增刪改查
  6. 基於 abp vNext 和 .NET Core 開發博客項目 – 統一規範API,包裝返回模型
  7. 基於 abp vNext 和 .NET Core 開發博客項目 – 再說Swagger,分組、描述、小綠鎖
  8. 基於 abp vNext 和 .NET Core 開發博客項目 – 接入GitHub,用JWT保護你的API
  9. 基於 abp vNext 和 .NET Core 開發博客項目 – 異常處理和日誌記錄
  10. 基於 abp vNext 和 .NET Core 開發博客項目 – 使用Redis緩存數據
  11. 基於 abp vNext 和 .NET Core 開發博客項目 – 集成Hangfire實現定時任務處理
  12. 基於 abp vNext 和 .NET Core 開發博客項目 – 用AutoMapper搞定對象映射
  13. 基於 abp vNext 和 .NET Core 開發博客項目 – 定時任務最佳實戰(一)
  14. 基於 abp vNext 和 .NET Core 開發博客項目 – 定時任務最佳實戰(二)
  15. 基於 abp vNext 和 .NET Core 開發博客項目 – 定時任務最佳實戰(三)
  16. 基於 abp vNext 和 .NET Core 開發博客項目 – 博客接口實戰篇(一)
  17. 基於 abp vNext 和 .NET Core 開發博客項目 – 博客接口實戰篇(二)
  18. 基於 abp vNext 和 .NET Core 開發博客項目 – 博客接口實戰篇(三)
  19. 基於 abp vNext 和 .NET Core 開發博客項目 – 博客接口實戰篇(四)
  20. 基於 abp vNext 和 .NET Core 開發博客項目 – 博客接口實戰篇(五)
  21. 基於 abp vNext 和 .NET Core 開發博客項目 – Blazor 實戰系列(一)
  22. 基於 abp vNext 和 .NET Core 開發博客項目 – Blazor 實戰系列(二)
  23. 基於 abp vNext 和 .NET Core 開發博客項目 – Blazor 實戰系列(三)
  24. 基於 abp vNext 和 .NET Core 開發博客項目 – Blazor 實戰系列(四)
  25. 基於 abp vNext 和 .NET Core 開發博客項目 – Blazor 實戰系列(五)
  26. 基於 abp vNext 和 .NET Core 開發博客項目 – Blazor 實戰系列(六)
  27. 基於 abp vNext 和 .NET Core 開發博客項目 – Blazor 實戰系列(七)
  28. 基於 abp vNext 和 .NET Core 開發博客項目 – Blazor 實戰系列(八)
  29. 基於 abp vNext 和 .NET Core 開發博客項目 – Blazor 實戰系列(九)
  30. 基於 abp vNext 和 .NET Core 開發博客項目 – 終結篇之發布項目

上一篇(https://www.cnblogs.com/meowv/p/12971041.html)使用HtmlAgilityPack抓取壁紙數據成功將圖片存入數據庫,本篇繼續來完成一個全網各大平台的熱點新聞數據的抓取。

同樣的,可以先預覽一下我個人博客中的成品:https://meowv.com/hot ,和抓取壁紙的套路一樣,大同小異。

本次要抓取的源有18個,分別是博客園、V2EX、SegmentFault、掘金、微信熱門、豆瓣精選、IT之家、36氪、百度貼吧、百度熱搜、微博熱搜、知乎熱榜、知乎日報、網易新聞、GitHub、抖音熱點、抖音視頻、抖音正能量。

還是將數據存入數據庫,按部就班先將實體類和自定義倉儲創建好,實體取名HotNews。貼一下代碼:

//HotNews.cs
using System;
using Volo.Abp.Domain.Entities;

namespace Meowv.Blog.Domain.HotNews
{
    public class HotNews : Entity<Guid>
    {
        /// <summary>
        /// 標題
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// 鏈接
        /// </summary>
        public string Url { get; set; }

        /// <summary>
        /// SourceId
        /// </summary>
        public int SourceId { get; set; }

        /// <summary>
        /// 創建時間
        /// </summary>
        public DateTime CreateTime { get; set; }
    }
}

剩下的大家自己完成,最終數據庫生成一張空的數據表,meowv_hotnews 。

然後還是將我們各大平台放到一個枚舉類HotNewsEnum.cs中。

//HotNewsEnum.cs
using System.ComponentModel;

namespace Meowv.Blog.Domain.Shared.Enum
{
    public enum HotNewsEnum
    {
        [Description("博客園")]
        cnblogs = 1,

        [Description("V2EX")]
        v2ex = 2,

        [Description("SegmentFault")]
        segmentfault = 3,

        [Description("掘金")]
        juejin = 4,

        [Description("微信熱門")]
        weixin = 5,

        [Description("豆瓣精選")]
        douban = 6,

        [Description("IT之家")]
        ithome = 7,

        [Description("36氪")]
        kr36 = 8,

        [Description("百度貼吧")]
        tieba = 9,

        [Description("百度熱搜")]
        baidu = 10,

        [Description("微博熱搜")]
        weibo = 11,

        [Description("知乎熱榜")]
        zhihu = 12,

        [Description("知乎日報")]
        zhihudaily = 13,

        [Description("網易新聞")]
        news163 = 14,

        [Description("GitHub")]
        github = 15,

        [Description("抖音熱點")]
        douyin_hot = 16,

        [Description("抖音視頻")]
        douyin_video = 17,

        [Description("抖音正能量")]
        douyin_positive = 18
    }
}

和上一篇抓取壁紙一樣,做一些準備工作。

.Application.Contracts層添加HotNewsJobItem<T>,在.BackgroundJobs層添加HotNewsJob用來處理爬蟲邏輯,用構造函數方式注入倉儲IHotNewsRepository

//HotNewsJobItem.cs
using Meowv.Blog.Domain.Shared.Enum;

namespace Meowv.Blog.Application.Contracts.HotNews
{
    public class HotNewsJobItem<T>
    {
        /// <summary>
        /// <see cref="Result"/>
        /// </summary>
        public T Result { get; set; }

        /// <summary>
        /// 來源
        /// </summary>
        public HotNewsEnum Source { get; set; }
    }
}
//HotNewsJob.CS
using Meowv.Blog.Domain.HotNews.Repositories;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace Meowv.Blog.BackgroundJobs.Jobs.HotNews
{
    public class HotNewsJob : IBackgroundJob
    {
        private readonly IHttpClientFactory _httpClient;
        private readonly IHotNewsRepository _hotNewsRepository;

        public HotNewsJob(IHttpClientFactory httpClient,
                          IHotNewsRepository hotNewsRepository)
        {
            _httpClient = httpClient;
            _hotNewsRepository = hotNewsRepository;
        }

        public async Task ExecuteAsync()
        {
            throw new NotImplementedException();
        }
    }
}

接下來明確數據源地址,因為以上數據源有的返回是HTML,有的直接返回JSON數據。為了方便調用,我這裏還注入了IHttpClientFactory

整理好的待抓取數據源列表是這樣的。

...
var hotnewsUrls = new List<HotNewsJobItem<string>>
{
    new HotNewsJobItem<string> { Result = "https://www.cnblogs.com", Source = HotNewsEnum.cnblogs },
    new HotNewsJobItem<string> { Result = "https://www.v2ex.com/?tab=hot", Source = HotNewsEnum.v2ex },
    new HotNewsJobItem<string> { Result = "https://segmentfault.com/hottest", Source = HotNewsEnum.segmentfault },
    new HotNewsJobItem<string> { Result = "https://web-api.juejin.im/query", Source = HotNewsEnum.juejin },
    new HotNewsJobItem<string> { Result = "https://weixin.sogou.com", Source = HotNewsEnum.weixin },
    new HotNewsJobItem<string> { Result = "https://www.douban.com/group/explore", Source = HotNewsEnum.douban },
    new HotNewsJobItem<string> { Result = "https://www.ithome.com", Source = HotNewsEnum.ithome },
    new HotNewsJobItem<string> { Result = "https://36kr.com/newsflashes", Source = HotNewsEnum.kr36 },
    new HotNewsJobItem<string> { Result = "http://tieba.baidu.com/hottopic/browse/topicList", Source = HotNewsEnum.tieba },
    new HotNewsJobItem<string> { Result = "http://top.baidu.com/buzz?b=341", Source = HotNewsEnum.baidu },
    new HotNewsJobItem<string> { Result = "https://s.weibo.com/top/summary/summary", Source = HotNewsEnum.weibo },
    new HotNewsJobItem<string> { Result = "https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=50&desktop=true", Source = HotNewsEnum.zhihu },
    new HotNewsJobItem<string> { Result = "https://daily.zhihu.com", Source = HotNewsEnum.zhihudaily },
    new HotNewsJobItem<string> { Result = "http://news.163.com/special/0001386F/rank_whole.html", Source = HotNewsEnum.news163 },
    new HotNewsJobItem<string> { Result = "https://github.com/trending", Source = HotNewsEnum.github },
    new HotNewsJobItem<string> { Result = "https://www.iesdouyin.com/web/api/v2/hotsearch/billboard/word", Source = HotNewsEnum.douyin_hot },
    new HotNewsJobItem<string> { Result = "https://www.iesdouyin.com/web/api/v2/hotsearch/billboard/aweme", Source = HotNewsEnum.douyin_video },
    new HotNewsJobItem<string> { Result = "https://www.iesdouyin.com/web/api/v2/hotsearch/billboard/aweme/?type=positive", Source = HotNewsEnum.douyin_positive },
};
...

其中有幾個比較特殊的,掘金、百度熱搜、網易新聞。

掘金需要發送Post請求,返回的是JSON數據,並且需要指定特有的請求頭和請求數據,所以使用IHttpClientFactory創建了HttpClient對象。

百度熱搜、網易新聞兩個老大哥玩套路,網頁編碼是GB2312的,所以要專門為其指定編碼方式,不然取到的數據都是亂碼。

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

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

...
var web = new HtmlWeb();
var list_task = new List<Task<HotNewsJobItem<object>>>();

hotnewsUrls.ForEach(item =>
{
    var task = Task.Run(async () =>
    {
        var obj = new object();

        if (item.Source == HotNewsEnum.juejin)
        {
            using var client = _httpClient.CreateClient();
            client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.14 Safari/537.36 Edg/83.0.478.13");
            client.DefaultRequestHeaders.Add("X-Agent", "Juejin/Web");
            var data = "{\"extensions\":{\"query\":{ \"id\":\"21207e9ddb1de777adeaca7a2fb38030\"}},\"operationName\":\"\",\"query\":\"\",\"variables\":{ \"first\":20,\"after\":\"\",\"order\":\"THREE_DAYS_HOTTEST\"}}";
            var buffer = data.SerializeUtf8();
            var byteContent = new ByteArrayContent(buffer);
            byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            var httpResponse = await client.PostAsync(item.Result, byteContent);
            obj = await httpResponse.Content.ReadAsStringAsync();
        }
        else
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            obj = await web.LoadFromWebAsync(item.Result, (item.Source == HotNewsEnum.baidu || item.Source == HotNewsEnum.news163) ? Encoding.GetEncoding("GB2312") : Encoding.UTF8);
        }

        return new HotNewsJobItem<object>
        {
            Result = obj,
            Source = item.Source
        };
    });
    list_task.Add(task);
});
Task.WaitAll(list_task.ToArray());

循環 hotnewsUrls ,可以看到HotNewsJobItem我們返回的是object類型,因為有JSON又有HtmlDocument對象。所以這裏為了能夠統一接收,就是用了object。

針對掘金做了單獨處理,使用HttpClient發送Post請求,返回JSON字符串數據。

針對百度熱搜和網易新聞,使用Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);註冊編碼提供程序,然後在web.LoadFromWebAsync(...)加載網頁數據的時候指定網頁編碼,我使用了一個三元表達式來處理。

完成上面這一步,就可以循環 list_task,使用XPath語法,或者解析JSON數據,去拿到數據了。

...
var hotNews = new List<HotNews>();
foreach (var list in list_task)
{
    var item = await list;
    var sourceId = (int)item.Source;

    ...

    if (hotNews.Any())
    {
        await _hotNewsRepository.DeleteAsync(x => true);
        await _hotNewsRepository.BulkInsertAsync(hotNews);
    }
}

這個爬蟲同樣很簡單,只要拿到標題和鏈接即可,所以主要目標是尋找到頁面上的a標籤列表。這個我覺得也沒必要一個個去分析了,直接上代碼。

// 博客園
 if (item.Source == HotNewsEnum.cnblogs)
 {
     var nodes = ((HtmlDocument)item.Result).DocumentNode.SelectNodes("//div[@class='post_item_body']/h3/a").ToList();
     nodes.ForEach(x =>
     {
         hotNews.Add(new HotNews
         {
             Title = x.InnerText,
             Url = x.GetAttributeValue("href", ""),
             SourceId = sourceId,
             CreateTime = DateTime.Now
         });
     });
 }
// V2EX
if (item.Source == HotNewsEnum.v2ex)
{
    var nodes = ((HtmlDocument)item.Result).DocumentNode.SelectNodes("//span[@class='item_title']/a").ToList();
    nodes.ForEach(x =>
    {
        hotNews.Add(new HotNews
        {
            Title = x.InnerText,
            Url = $"https://www.v2ex.com{x.GetAttributeValue("href", "")}",
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    });
}
 // SegmentFault
 if (item.Source == HotNewsEnum.segmentfault)
 {
     var nodes = ((HtmlDocument)item.Result).DocumentNode.SelectNodes("//div[@class='news__item-info clearfix']/a").Where(x => x.InnerText.IsNotNullOrEmpty()).ToList();
     nodes.ForEach(x =>
     {
         hotNews.Add(new HotNews
         {
             Title = x.SelectSingleNode(".//h4").InnerText,
             Url = $"https://segmentfault.com{x.GetAttributeValue("href", "")}",
             SourceId = sourceId,
             CreateTime = DateTime.Now
         });
     });
 }
// 掘金
if (item.Source == HotNewsEnum.juejin)
{
    var obj = JObject.Parse((string)item.Result);
    var nodes = obj["data"]["articleFeed"]["items"]["edges"];
    foreach (var node in nodes)
    {
        hotNews.Add(new HotNews
        {
            Title = node["node"]["title"].ToString(),
            Url = node["node"]["originalUrl"].ToString(),
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    }
}
// 微信熱門
if (item.Source == HotNewsEnum.weixin)
{
    var nodes = ((HtmlDocument)item.Result).DocumentNode.SelectNodes("//ul[@class='news-list']/li/div[@class='txt-box']/h3/a").ToList();
    nodes.ForEach(x =>
    {
        hotNews.Add(new HotNews
        {
            Title = x.InnerText,
            Url = x.GetAttributeValue("href", ""),
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    });
}
// 豆瓣精選
if (item.Source == HotNewsEnum.douban)
{
    var nodes = ((HtmlDocument)item.Result).DocumentNode.SelectNodes("//div[@class='channel-item']/div[@class='bd']/h3/a").ToList();
    nodes.ForEach(x =>
    {
        hotNews.Add(new HotNews
        {
            Title = x.InnerText,
            Url = x.GetAttributeValue("href", ""),
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    });
}
// IT之家
if (item.Source == HotNewsEnum.ithome)
{
    var nodes = ((HtmlDocument)item.Result).DocumentNode.SelectNodes("//div[@class='lst lst-2 hot-list']/div[1]/ul/li/a").ToList();
    nodes.ForEach(x =>
    {
        hotNews.Add(new HotNews
        {
            Title = x.InnerText,
            Url = x.GetAttributeValue("href", ""),
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    });
}
// 36氪
if (item.Source == HotNewsEnum.kr36)
{
    var nodes = ((HtmlDocument)item.Result).DocumentNode.SelectNodes("//div[@class='hotlist-main']/div[@class='hotlist-item-toptwo']/a[2]|//div[@class='hotlist-main']/div[@class='hotlist-item-other clearfloat']/div[@class='hotlist-item-other-info']/a").ToList();
    nodes.ForEach(x =>
    {
        hotNews.Add(new HotNews
        {
            Title = x.InnerText,
            Url = $"https://36kr.com{x.GetAttributeValue("href", "")}",
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    });
}
// 百度貼吧
if (item.Source == HotNewsEnum.tieba)
{
    var obj = JObject.Parse(((HtmlDocument)item.Result).ParsedText);
    var nodes = obj["data"]["bang_topic"]["topic_list"];
    foreach (var node in nodes)
    {
        hotNews.Add(new HotNews
        {
            Title = node["topic_name"].ToString(),
            Url = node["topic_url"].ToString().Replace("amp;", ""),
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    }
}
// 百度熱搜
if (item.Source == HotNewsEnum.baidu)
{
    var nodes = ((HtmlDocument)item.Result).DocumentNode.SelectNodes("//table[@class='list-table']//tr/td[@class='keyword']/a[@class='list-title']").ToList();
    nodes.ForEach(x =>
    {
        hotNews.Add(new HotNews
        {
            Title = x.InnerText,
            Url = x.GetAttributeValue("href", ""),
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    });
}
// 微博熱搜
if (item.Source == HotNewsEnum.weibo)
{
    var nodes = ((HtmlDocument)item.Result).DocumentNode.SelectNodes("//table/tbody/tr/td[2]/a").ToList();
    nodes.ForEach(x =>
    {
        hotNews.Add(new HotNews
        {
            Title = x.InnerText,
            Url = $"https://s.weibo.com{x.GetAttributeValue("href", "").Replace("#", "%23")}",
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    });
}
// 知乎熱榜
if (item.Source == HotNewsEnum.zhihu)
{
    var obj = JObject.Parse(((HtmlDocument)item.Result).ParsedText);
    var nodes = obj["data"];
    foreach (var node in nodes)
    {
        hotNews.Add(new HotNews
        {
            Title = node["target"]["title"].ToString(),
            Url = $"https://www.zhihu.com/question/{node["target"]["id"]}",
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    }
}
// 知乎日報
if (item.Source == HotNewsEnum.zhihudaily)
{
    var nodes = ((HtmlDocument)item.Result).DocumentNode.SelectNodes("//div[@class='box']/a").ToList();
    nodes.ForEach(x =>
    {
        hotNews.Add(new HotNews
        {
            Title = x.InnerText,
            Url = $"https://daily.zhihu.com{x.GetAttributeValue("href", "")}",
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    });
}
// 網易新聞
if (item.Source == HotNewsEnum.news163)
{
    var nodes = ((HtmlDocument)item.Result).DocumentNode.SelectNodes("//div[@class='area-half left']/div[@class='tabBox']/div[@class='tabContents active']/table//tr/td[1]/a").ToList();
    nodes.ForEach(x =>
    {
        hotNews.Add(new HotNews
        {
            Title = x.InnerText,
            Url = x.GetAttributeValue("href", ""),
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    });
}
// GitHub
if (item.Source == HotNewsEnum.github)
{
    var nodes = ((HtmlDocument)item.Result).DocumentNode.SelectNodes("//article[@class='Box-row']/h1/a").ToList();
    nodes.ForEach(x =>
    {
        hotNews.Add(new HotNews
        {
            Title = x.InnerText.Trim().Replace("\n", "").Replace(" ", ""),
            Url = $"https://github.com{x.GetAttributeValue("href", "")}",
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    });
}
// 抖音熱點
if (item.Source == HotNewsEnum.douyin_hot)
{
    var obj = JObject.Parse(((HtmlDocument)item.Result).ParsedText);
    var nodes = obj["word_list"];
    foreach (var node in nodes)
    {
        hotNews.Add(new HotNews
        {
            Title = node["word"].ToString(),
            Url = $"#{node["hot_value"]}",
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    }
}
// 抖音視頻 & 抖音正能量
if (item.Source == HotNewsEnum.douyin_video || item.Source == HotNewsEnum.douyin_positive)
{
    var obj = JObject.Parse(((HtmlDocument)item.Result).ParsedText);
    var nodes = obj["aweme_list"];
    foreach (var node in nodes)
    {
        hotNews.Add(new HotNews
        {
            Title = node["aweme_info"]["desc"].ToString(),
            Url = node["aweme_info"]["share_url"].ToString(),
            SourceId = sourceId,
            CreateTime = DateTime.Now
        });
    }
}

item.Result轉換成指定類型,最終拿到數據后,我們先刪除所有數據后再批量插入。

然後新建擴展方法UseHotNewsJob(),在模塊類中調用。

//MeowvBlogBackgroundJobsExtensions.cs
...
        /// <summary>
        /// 每日熱點數據抓取
        /// </summary>
        /// <param name="context"></param>
        public static void UseHotNewsJob(this IServiceProvider service)
        {
            var job = service.GetService<HotNewsJob>();

            RecurringJob.AddOrUpdate("每日熱點數據抓取", () => job.ExecuteAsync(), CronType.Hour(1, 2));
        }
...

指定定時任務為每2小時運行一次。

...
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            ...
            var service = context.ServiceProvider;
            ...
            service.UseHotNewsJob();
        }

編譯運行,此時周期性作業就會出現我們的定時任務了。

默認時間沒到是不會執行的,我們手動執行等待一會看看效果。

執行完成后,成功將所有熱點數據保存在數據庫中,說明我們的爬蟲已經搞定了,並且Hangfire會按照給定的規則去循環執行,你學會了嗎?

開源地址:https://github.com/Meowv/Blog/tree/blog_tutorial

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

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

一篇文章,全面掌握Git_貨運

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

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

版本控制

版本控制就是記錄項目文件的歷史變化。它為我們查閱日誌回退協作等方面提供了有力的幫助。

版本控制一般分為集中化版本控制和分佈式版本控制。

集中化主要的版本數據都保存服務端。

分佈式版本數據分散在多端。

Git

Git屬於分佈式版本控制,也是現在比較流行的一種版本管理工具。

Git項目有三個區塊:工作區 / 暫存區 / 版本庫

  • 工作區存放從版本庫提取出來的文件,供我們編輯修改;
  • 暫存區保存了下一次要提交的目錄信息;
  • 版本庫保存項目版本元數據和Objects數據,後文會詳解。

Git工作流程

# 下載
<<==== clone 
# 上傳
====>> add ====>> commit ====>> push
# 更新
<<==== merge|rebase <<===== fetch

區分 Pull vs Fetch

我們將一個更新操作拆分為數據更新+合併處理兩部分,這樣來看 fetch 只是進行數據更新。而pull 其實是 ( fetch + (merge|rebase) )組合操作,它執行數據更新同時執行合併處理。pull 默認是fetch+merge 組合 ,也可以通過參數 –rebase 指定為 fetch + rebase。

區分Merge vs Rebase

合併處理是Git很重要的一塊知識。兩個命令在工作中也經常使用,區分它們對我們很有用。

場景如下

項目有一個mywork分支。C2時間點我和小明各自下載項目進行功能開發,小明效率比較高,先推送了C3 C4 到遠程倉庫。我本地倉庫現在有C5 C6兩個提交,要推送到遠程倉庫,需先同步遠程倉庫版本。

如果通過 fetch + merge 方式,Git會將遠程最新(C4)和本地最新(C6)進行合併併產生一個新的(C7)。

衝突處理步驟

git merge # 發生衝突會出現衝突標記
“<<<<<<< HEAD
40
=======
41
>>>>>>> 41”
# 手動處理衝突
git add .
git commit -m 'fix conflict'
git push origin HEAD

如果通過 fetch + rebase 方式,git會先將C5 C6存儲到.git/rebase零時目錄,合併成功后刪除。

衝突處理步驟

git rebase # 發生衝突會出現衝突標記
“<<<<<<< HEAD
40
=======
41
>>>>>>> 41”
# 手動處理衝突
git add .
git rebase --continue
git push origin HEAD

小結

git merge 會產生大量Merge日誌,可能會對查看帶來不便。不過大家還是根據實際情況進行選取。

關於撤銷回退幾種場景

提交后發現有文件漏了,又不想提交兩次。此時通過 “git commit –amend” 可以合併為一個提交。

git commit -m 'initial commit'
git add .gitignore
git commit --amend

如果文件想撤回且尚未提交,執行下面命令撤出暫存空間(index)

git reset HEAD <file>...

關於 reset 其它用法

# 重置到指定版本,之前提交內容將丟失
git reset --hard HEAD 
# 重置到指定版本,保留更改的文件但未標記為提交
git reset --mixed HEAD 
# 重置到指定版本,保留所有改動文件
git reset –soft HEAD 

特別注意 當你使用 “git reset –hard HEAD” 重置到某一版本,發現搞錯了想回退。這時你可能會執行“git log”,但是發現已經沒有以前的版本記錄,怎麼辦?送你一瓶後悔葯如下

# reflog 是Git操作的全日誌記錄
git reflog

6241462 (HEAD -> master) HEAD@{0}: reset: moving to 6241462
ea9b5ab HEAD@{1}: reset: moving to ea9b5ab
6241462 (HEAD -> master) HEAD@{2}: commit: Hello
34cd1e3 HEAD@{3}: commit: 3
ea9b5ab HEAD@{4}: commit: 2
729a8b1 (origin/master) HEAD@{5}: commit (initial): 1

# 找到最左邊對應hash值就可以回退到任意位置
git reset --hard {index}

如果想撤迴文件修改內容且文件尚未提交,執行下面命令

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

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

git checkout -- <file>

如果創建的分支名稱需要更改

git branch -m old new

# 如果分支已經推送到遠程,先刪除再推送新分支
git push origin --delete old
git push origin new

如果需要撤回的提交已經推送到了遠程倉庫,那麼補救的方式只有創建新的提交。

可以利用revert快速撤回到需要回退的版本。

# 還原最近一個提交
git revert HEAD
# 還原倒數第二個
git revert HEAD^
# 還原倒數第第四個
git revert HEAD~3

版本庫 Objects

這一節介紹一下Git版本庫的存儲模型。

項目歷史變動信息都記錄在object文件。文件名稱是通過哈希算法 ( 這裡是SHA1(對象內容) ) 產生的40位字符。

這種做法的一個優點就是“在對比兩對象是否相同時,只需要比較文件名稱就能迅速得出結果”

哈希算法:簡單來說就是向函數輸入一些內容,輸出長度固定的字符串。這裏SHA1函數固定輸出40長度字符。

object文件分 blob tree commit tag 四種類型

  • blob 存儲文件數據,一般是一個文件;

  • tree 存儲目錄和樹的引用(子文件目錄);

  • commit 存儲單一樹引用,時間點,提交作者,上一次提交指針;

  • tag 標記特定的commit 比如說發版。

特別注意:Subversion,CVS,Perforce,Mercurial等是存儲前後兩次提交的差異數據。Gi-每次提交時,它都會以樹狀結構存儲項目中所有文件的外觀快照。

Blob

Blob 是二進制數據塊,不會引用其它東西。如果目錄樹(或存儲庫中多個不同版本)中的兩個文件具有內容相同,它們將共享相同的Blob對象。

Tree

Tree 存儲blob和tree的引用。

# 我查詢 add1a1306e20...
git ls-tree add1a1306e20...

100644 blob 4661b39c3460a5c1f9e9309e6341962e0499b037	README.md
040000 tree ad46b24a4b0648ede3ca090dde32c89b89f7f2c1	src
...

Commit

Commit 包含下面幾個信息

  1. tree 提交時間點的目錄;
  2. parent 上一個提交;
  3. author 提交人;
git show -s --pretty=raw add1a1306e....

commit add1a1306e....
tree 81d4e4271a56575da7f992dc0dfc72ff7ddff94c
parent cd397e4c373013b19825b857b43ad8f677607f5d
author lixingping <lixingping233@gmail.com> 1589783810 +0800
committer lixingping <lixingping233@gmail.com> 1589783810 +0800

Tag

git cat-file tag v_1.0

object 24d16acd6aa08f74556c7ce551fa571b4bfe4079
type commit
tag v_1.0
tagger lixingping <lixingping233@gmail.com> 1588591122 +0800

例子

假設項目目錄結構如下,我們進行一個初始提交。幾種文件關係如下圖

|-- read.txt
    --| lib
      --| hello.java

附上一些常用命令

生成SSH key

ssh-keygen -t rsa -b 4096 -C "email@example.com"
# 指定生成的文件
ssh-keygen -t rsa -b 4096 -C "email@example.com" -f ~/.ssh/id_rsa_example
# id_rsa_example.pub 粘貼遠程倉庫

# 配置多個遠程倉庫
touch ~/.ssh/config

#添加一下內容
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_github

Host example.com
HostName example.com
User git
IdentityFile ~/.ssh/id_rsa_example

配置

git config –global user.name “xxx”
git config –global user.email “xxx@email.com“
git config --global core.autocrlf true # 建議配置 windows mac換行符不統一問題
git config --global core.editor vim # 配置默認編輯器
git config --global core.excludesfile ~/.gitignore_global # 配置全局忽略文件
git config –list # 查看配置信息

分支管理

git branch --list # 羅列本地所有分支
git branch --all  # 羅列本地和遠程所有分支
git branch -r     # 羅列遠程所有分支
git branch -v     # 显示各分支最後提交信息
git checkout <branch name> # 切換分支
git checkout -b <new branch name> # 創建新分支
git push origin <new branch name> # 推送新分支到遠程
git checkout -m <old branch> <new branch> # 重命名分支名稱
git branch -d <[list]branch name> # 刪除本地分支
git push origin --delete <branch name> # 刪除遠程分支

標籤管理

git tag -l # 羅列本地所有標籤
git show <tag name> # 显示指定標籤
git tag -a v_1.0.0 -m "備註" # 創建標籤
git push origin <tag name> # 推送標籤到遠程
git tag -d <tag name> # 刪除本地標籤
git push --delete origin <tag name> # 刪除遠程標籤

總結

工作多年以來一直在使用Git,但是對Git沒有一個系統了解,所以寫這篇文章歸整一下。

歡迎大家留言交流,一起學習分享!!!

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

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

SUV確實很火 但這幾款真正品質出色的SUV為何沒啥人關注?_網頁設計

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

網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品

39-30。19萬福特 撼路者售價:26。58-36。08萬英菲尼迪 QX50售價:34。98-44。98萬總結:其實一款汽車真的在市場上的反響不好,可能有着各種的原因。有些事可能目前整個市場的份額開始萎縮,但究其基本,一款本就比較出色的車型沒有收到消費者的歡迎,最終還是價格不夠親民影響了它最後的銷量,因此做好一款車需要時間與金錢,同時賣好一款車也同樣需要智慧。

對於目前的汽車市場,相比前些年已經發生了不少的變化。之前的一段時間可能大家買車的時候都在關注小型車為主,有些改善型買家則偏向於一些高品質的中型車為主,只是時代是在發展的。消費者的胃口也是跟着發生變化,

※推薦評價好的iphone維修中心

擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

這些年當中,SUV已經從當年的嶄露頭角變成了消費者購車的首選了。但就是這樣的背景下,一些品質非常出眾,但市場的反應卻依然不太好,為何有這樣的原因呢,今天就給你好好說道說道。

售價:22.48-28.98萬

售價:19.39-30.19萬

售價:26.58-36.08萬

售價:34.98-44.98萬

總結:其實一款汽車真的在市場上的反響不好,可能有着各種的原因。有些事可能目前整個市場的份額開始萎縮,但究其基本,一款本就比較出色的車型沒有收到消費者的歡迎,最終還是價格不夠親民影響了它最後的銷量,因此做好一款車需要時間與金錢,同時賣好一款車也同樣需要智慧。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。

【JVM】垃圾回收的四大算法_貨運

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

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

GC垃圾回收

JVM大部分時候回收的都是新生代(伊甸區+倖存0區+倖存1區)。按照回收的區域可以分成兩種類型:Minor GC和Full GC(MajorGC)。

  • Minor GC:只針對新生代區域的GC,大多數Java對象的存活率都不高,Minor GC非常頻繁,回收速度快。
  • Full GC:發生在老年代的GC,經常會伴隨至少一次的Minor GC(但不一定會),Full GC掃描的範圍更廣泛,Full GC的速度比Minor GC慢10倍以上。

 

 

GC四大算法

引用計數法

對於單個對象來說,當有引用發生,引用計數器就+1;當丟失引用,引用計數器就-1。當引用數減到0的時候,說明對象不再有用,被垃圾回收。引用計數法缺點是每次對對象賦值都要維護引用計數器,且計數器本身也有一定的消耗,難以處理引用循環(例如:對象雙方互相引用,但實際上二者為空,此時雙方引用都不為空)。JVM的實現一般不採用這種方式。

複製算法

年輕代中使用的是Minor GC,這種Minor GC採用的是複製算法。複製的思想是將內存分為2快,每次只用其中一塊,當這一塊內存用完,就將或者的對象複製到另一塊上面,複製算法不會產生內存碎片

HotSpot JVM中年輕代可以分成三個部分:Eden區、Survivor0區,Survivor1區,默認比例為8:1:1。Survivor的兩個區在邏輯上可以視為from區和to區,每次GC後會交換from區和to區,在Eden區和from區滿之前,to區始終是為空的區。如果to區也被填滿了,所有對象移動到老年代。

新創建的對象一般會被分配到伊甸區,經過一次Minor GC后,如果對象還存活,就會被移到Survivor區。from區的對象如果繼續存活,且能夠被另一塊倖存區to區容納,則使用複製算法將這些仍然存活的的對象複製到另一塊倖存區to區中,然後清理使用過的Eden和from區(下一次分配就從to區開始,to區成為下一次GC的from區),且這些對象的年齡設置為1,以後對象在倖存區每經歷一次Minor GC,對象的年齡就會+1,當對象的年齡到達某個閾值的時候,這些對象就會進入老年代。(閾值默認是15,可以通過-XX:MaxTenuringThreshhold來設定對象在新生代在存活的次數)。

這種算法的優點了不會產生內存碎片,缺點是浪費內存空間,在HotSpot虛擬機中8:1:1的比例下,可用內存為80%+10%,有10%的內存會被浪費掉。如果對象存活率很高,就需要將所有對象都複製一邊,並重置引用地址。

標記清除(Mark-Sweep)

老年代一般是由標記清除 或者 標記清除和標記整理的混合實現的。

標記清除算法分為兩個步驟,先標記出要回收的對象,然後統一回收這些對象。

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

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

優點是節約內存空間,不需要額外空間。缺點是兩次掃描,標記和清除的效率都不高,耗時嚴重。標記清除後會產生大量不連續的內存碎片。內存碎片會導致以後程序需要分配大對象的時候,找不到足夠的連續內存,導致提前觸發GC。

 標記整理(Mark-Compact)

和標記清除一樣,先標記出要回收的對象,然後讓存活對象都向一端移動,直接清理掉端邊界 以外的內存。

優點是沒有內存碎片,缺點是效率不高,需要標記存活對象還要整理存活對象的引用地址,從效率上來說是不如複製算法的。

還有一種折衷的方案,將標記清除和標記整理算法相結合,一般直接標記清除,當GC達到一定次數的時候,進行一次標記整理,從而減少了移動對象的成本,又有處理內存碎片的步驟。

總結

效率排名:複製算法>標記清除>標記整理

內存整齊度:複製算法=標記整理>標記清理

內存利用率:標記整理=標記清理>複製算法

四種算法各有優劣,一般的JVM實現會採用分代收集算法,根據不同代所具有的不同特點使用不同的算法。

年輕代的特點是區域較小,對象存活率低,適合使用複製算法。複製算法的效率只和當前存活對象的大小有關,適用於年輕代的回收,內存利用率不高的問題HotSopt通過兩個survivor的設計進行和緩解,新生代可用容量為80%+10%,只有10%的內存被浪費掉。

老年代的特點是區域較大,對象存活率高,適合使用標記清除/標記整理算法。

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

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

Python裝飾器的一點解讀_貨運

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

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

  版權申明:本文為博主窗戶(Colin Cai)原創,歡迎轉帖。如要轉貼,必須註明原文網址

  http://www.cnblogs.com/Colin-Cai/p/12977127.html 

  作者:窗戶

  QQ/微信:6679072

  E-mail:6679072@qq.com

  理論上,函數是一等公民(first class function)的語言都可以使用函數式編程,從而利用算子(高階函數)來做裝飾器。

  裝飾器一般是這樣一個算子,它接受一個函數作為參數,返回另外一個函數。裝飾器,顧名思義,就是把一個函數“裝飾”一下,得到另外一個函數。為何要裝飾一下呢?目的一般是可能設計上需要對函數做一些改裝,比如原函數輸出結果需要再加工加工,或者原函數的輸入參數傳入不一樣,或者兩者兼有之,等等。

 

  迭代是編程中常用的手段,它的計算方式表現為狀態的不斷變換,且狀態的變換具有唯一性。

  比如我們使用Scheme來表示迭代。

;stat代表當前狀態,next代表狀態改變函數,final?代表判斷狀態是否終止
(define (iterate-orgin stat next final?)
  (if (final? stat)
      stat
      (iterate-orgin (next stat) next final?)))

;將next函數和final?函數封成一個函數
(define (iterate stat f-stat)
  (iterate-orgin stat (f-stat 'next) (f-stat 'final)))

;最終我們需要的迭代函數
(define (it f-stat)
  (lambda (stat) (iterate stat f-stat)))

  

  以上構造出一個算子it,就是用來“裝飾”迭代的函數。

  我們構造一個對list求和的迭代:

  可以每次把list的前面兩個相加,比如對(1 2 3 4 5)求和,經過以下狀態:

  (1 2 3 4 5)

  (3 3 4 5)

  (6 4 5)

  (10 5)

  (15)

  15

  得到最後結果15。

  代碼可以如下:

(define (make-sum-func sym)
 (if (eq? sym 'next);next函數
  (lambda (lst)
   (if (pair? lst)
    (if (null? (cdr lst))
     (car lst)
     (cons (+ (car lst) (cadr lst)) (cddr lst)))
    lst))
  (if (eq? sym 'final?);final?函數
   (lambda (lst) (not (pair? lst)))
   '())))

 

  然後測試一下((it make-sum-func) ‘(1 2 3 4 5)),得到最後結果15。

  上面兩個函數寫在一起,我們還可以再分離一下。

  

;定義一個打包函數
(define (wrap-next-final next final?)
 (lambda (sym)
  (if (eq? sym 'next)
   next
   (if (eq? sym 'final?)
    final?
    '()))))

;下面next和final?兩個函數可以分開寫
(define make-sum-next
 (lambda (lst)
  (if (pair? lst)
   (if (null? (cdr lst))
    (car lst)
    (cons (+ (car lst) (cadr lst)) (cddr lst)))
   lst)))

(define make-sum-final?
 (lambda (lst) (not (pair? lst))))

;於是函數就可以下面這樣表示
(define make-sum-func (wrap-next-final make-sum-next make-sum-final?))

 

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

  總而言之,裝飾器就是這樣一類算子。

 

  Python也是這樣,只是Python提供了@這樣的語法,實際上是個語法糖,與其說是簡寫,倒是更像是個語法提醒這是一個裝飾器。

  我們這次希望來显示一下mysym,還是用求和。

  先寫一個簡單的mysum函數用於求和: 

def mysum(*args):
    ret = 0
    for i in args:
        ret += i
    return ret

 

  做一個算子,來擴充它的輸入參數:

  這裏需要用來判斷一個對象是否是可迭代對象,

  from collections import Iterable

  然後,如果判斷對象x是否是可迭代對象,只需要:

  isinstance(x, Iterable)

  算子如下:

from collections import Iterable
def args_expan(f):
    def f2(*args):
        lst = []
        for i in args:
            if isinstance(i, Iterable):
                lst.append(f(*i))
            else:
                lst.append(i)
        return f(*lst)
    return f2

 

  然後在mysum前添加裝飾器標誌

@args_expan
def mysum(*args):
    ret = 0
    for i in args:
        ret += i
    return ret

 

  測試如下:

print(mysum(1,2,3,4,5))
print(mysum((1,2,3,4,5)))
print(mysum([1,2,3,4,5]))
print(mysum(range(1,6)))
print(mysum(map(lambda x:x+1, range(5))))
print(mysum(filter(lambda x:x<6, range(10))))

#構造了一個生成器
def gen_range(a, b):
    while a < b:
        yield a
        a += 1

print(mysum(\
    filter(lambda x:x<6, range(10)), \
    6, \
    [7,8], \
    (9, 10), \
    map(lambda x:x+11, range(10)), \
    gen_range(21,101)))

 

  運行得到:

15
15
15
15
15
15
5050

  終於看到,函數功能已被擴充。

  這個裝飾器還可以裝飾別的函數,比如乘積、統計等。

 

  從而,裝飾器就是這樣一個算子,一般用來改造函數的輸入或輸出,避免重複寫代碼。

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

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

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

小米推出小米便攜鼠標 2,內建雙模式可操作兩台電腦、4 段可調 DPI、一顆 5 號電池可用一年_貨運

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

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

小米便攜鼠標第一代推出至今也有超過二年的時間,依據其他產品的經驗,這款可說更新的相當慢,終於在稍早小米官方正式宣布二代「小米便攜鼠標 2」登場,除了延續上一代的雙模式特色外,還加入了 4 段可調 DPI 與更強悍的待機續航力,更重要是,價格還只需要 79 人民幣(約台幣 340 元),真的超值阿。

小米推出小米便攜鼠標 2

這次小米便攜鼠標 2 跟很多小米產品一樣,採用眾籌的方式開賣,眾籌價為 79 人民幣,預計 12/30 早上 10 開售,一直到 1/6 早上 10 點結束,隨後價格也會調整回零售的 99 人民幣(約台幣 425 元)。

就外型來看,小米便攜鼠標 2 跟上一代沒有太大差異,不過側面線條更佳時尚,也沒那麼厚,我覺得變得更好看,表面也採用細膩噴砂金屬處理,擁有耐磨耐腐蝕特性。另外雙模式(藍牙4.2 + USB 接收器)的按鍵也移到正面,使用上更容易:

搭載消耗功率低 Telink 藍牙晶片,並內建自動休眠技術,來降低待機功耗,實現更好的省電節能。根據官方測試數據,裝一顆 5 號電池,就能正常使用一整年的時間,用到後面你搞不好會以為它不需要裝電池。電量低於 10% 時,正面上方的 LED 紅燈也會亮起,來提醒使用者:

上一代 DPI 為固定的 1200,小米便攜鼠標 2 全新加入 4 段靈敏度調整,分別為 1200、1800、2400 與 4000,滿足使用者各種需求。DPI 功能鍵位於底部,切換時也會透過 LED 燈來提示你目前是什麼 DPI:

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

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

體積一樣相當輕巧,含電池僅 86 公克,攜帶上非常容易:

有白銀與黑灰兩種顏色。至於會不會進台灣,我是覺得有點難,畢竟第一代都沒有了。無論如何,有興趣入手的人還是可以透過集運之類方式,眾籌部分預計 1/13 起開始出貨:

多款小米筆電 Pro 現身 Geekbench,單核效能大幅提升

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

340 萬台,據報 PS5 破 PlayStation 首月出貨最高紀錄_貨運

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

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

雖然距離前代 PlayStation 4 突破億台的銷量還有很長一段路要走,不過身為 2020 年 Sony 端出的最強次世代主機,PlayStation 5 還是以各種開箱攻佔了各大媒體與社群平台的熱門話題。現在據報也已經以首四週 340 萬台的好銷售達到破紀錄的銷售成績。繼續閱讀 340 萬台,據報 PS5 破 PlayStation 首月出貨最高紀錄報導內文。

340 萬台,據報 PS5 破 PlayStation 首月出貨最高紀錄

缺貨到讓人又愛又恨的 PlayStation 5,很多也好奇到底這次的銷量成績與同樣都受到極高歡迎的先前幾代有沒有更強的銷售力道?是說,儘管在極度缺貨的日本,銷量表現似乎有所抑制(但我們還是搶先開箱日本版的 PlayStation 5 了)不過 Sony 這台次世代遊戲主機的全球銷量部分,現在已經從 Digitimes 關於出貨量的報導裡,間接揭露了 PlayStation 5 全球首四週的銷量,已直破以往自家主機的紀錄,來到 340 萬台的好成績。

是說,這篇報導主要劃的重點是在於緊接著在 2021 年初,得益於產線的改進年產量預估可達 1,680 萬至 1,800 萬台;1 月起將預留供貨給等得焦急的亞洲消費者(太好惹)。但對於 Sony 來說,這銷量相較於以往大受歡迎的 PS4(2018 年 8 月開賣至 12 月初,達到 210 萬台)應該真的讓他們有點措手不及吧,必須馬上修正提供更高的產量對應。

必須說,看來在這全人類都因為疫情悶得發慌的年代裡, PlayStation 5 出現的時間點也算是剛好對應了許多人居家娛樂的需求。

引用來源

延伸閱讀:

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

PlayStation 5 第一手搶先開箱!絕對是現今最值得入手的遊戲主機

iPhone 12 Pro Max 深度實拍體驗:ProRAW 讓 iPhone 踏入專業

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

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

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

性能再升級 斯巴魯BRZ GT官圖曝光_貨運

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

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

新款的斯巴魯BRZ GT車型是基於此前發布的新款BRZ打造的,外觀相比舊款車型的變化包括採用了經過重新設計的前保險杠,並換裝全LED頭尾燈組等。據了解到,BRZ GT將作為日規BRZ的高配車型銷售,其相比普通版BRZ增配了小型擾流板、新樣式的17英寸多輻式輪圈、Brembo布雷博制動系統以及SACHS品牌減振器等。

日前,斯巴魯發布了一組新款BRZ GT車型的官圖,新車將作為日規BRZ車系的高配車型進行銷售。其中手動擋車型起售價格為331.56萬日元(約合人民幣21.53萬元),自動擋車型起售價格為337.5萬日元(約合人民幣21.92萬元)。

新款的斯巴魯BRZ GT車型是基於此前發布的新款BRZ打造的,

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

外觀相比舊款車型的變化包括採用了經過重新設計的前保險杠,並換裝全LED頭尾燈組等。據了解到,BRZ GT將作為日規BRZ的高配車型銷售,其相比普通版BRZ增配了小型擾流板、新樣式的17英寸多輻式輪圈、Brembo布雷博制動系統以及SACHS品牌減振器等。

內飾方面,除新的多功能行車電腦显示屏和多功能方向盤外,新款BRZ GT還增加了由Alcantara搭配真皮材料包裹的運動座椅等。

動力部分,新款BRZ GT將沿用FA20型2.0L水平對置自然吸氣發動機,其最大輸出功率208馬力,峰值扭矩211牛·米,與新款BRZ的普通版車型一致。傳動系統匹配的依然是6速手動及6速手自一體變速箱。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

全台區間測速路段懶人包_貨運

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

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

今年上半年因省道台61線西濱公路彰化段區間測速發生爭議後,全台區間測速裝置大都多停用。經經濟部標準檢驗局訂定區間平均速率裝置檢定檢查技術規範後,警方將在2021年元月起陸續送檢37處裝置,待通過後就會加入執法。由於先前實施區間測速路段的超速罰單大增,倍增的區間測速路段上路後恐將成習慣飆速的汽車及機車車主荷包大失血。

什麼是【區間測速】? 超速會罰多少? 哪些路段將實施區間測速呢? 以下作一整理與說明:

掌握最新電信資費訊息,請加入小丰子3C俱樂部粉絲頁!

小丰子3C俱樂部

 

過去警察取締超速,大都採用固定式超速照相機,導致不少習慣超速開車的人都是快到固定式超速照相機地點才減速。為降低超速肇事,台灣警方參考國外做法自民國107年於新北市萬里隧道啟用【區間測速】,上路2年來共有18處區間測速裝置陸續加入執法,對於減少違規及降低交通事故發生有顯著成效。今年上半年因省道台61線西濱公路彰化段區間測速發生爭議而暫停後,在「區間平均速率裝置檢定檢查技術規範」110年元旦上路,警方將在全台裝置37處【區間測速】設施,陸續加入執法,多數路段最快2021年2月將重啟區間測速。以下是區間測速規定與目前全台預定實施路段:

 

1.區間測速規定:

「區間平均速率」指車輛行經某路段特定兩點之間(距離固定),除以所行駛的時間,即為平均速率。現行「雷達測速」也是偵測車輛在雷達波特定範圍內移動距離與時間差的關係計算車速(只是距離很短),一般認定是定點的測速,實際上也算是區間平均速率。
區間平均速率執法(簡稱區間測速),由點延伸為線,可大幅增加速率控制的有效範圍,除可抑制瞬間超速行為外,重點特色在於可減少車輛間行駛速度的差異,達到控制車行速度趨於穩定的效果,預期將會更有助減少事故發生。

 

區間測速大都使用在封閉或半封閉路段,且以常違規或易肇事的路段為主,實施區間測速的路段會設置「警52」警告牌面,一般道路設於起點前方100-300公尺(高快速公路為300-1000公尺),附牌文字為「前方區間測速長度○公里」。

 

在實施測速路段內必須依速限規定行駛,因速率係以平均值認定,故偶然不慎超速應不至於立刻構成違規,後續再注意減速即可,亦即存有補救之機會(固定桿則無)。以下是以台北市自強隧道通過的秒數換算車速。

 

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

行經區間測速路段若超速,將依行駛道路種類限速規定與透過經過時間換算的車速加以罰款。若是行駛快速道路超速逾10公里(時速101公里、通過時間約187秒)汽車罰緩至少3000元以上、6000元以下。汽、機車行駛限速50公里路段,時速60公里以上開罰,採累進制罰款,機車超速至少1200元、汽車超速至少1600元,各式車輛超速100公里以上均罰款2萬4千元,車輛超速愈高、罰款愈多。不管汽車或機車只要超速,就會收到以下超速照片與罰單通知。

 

2.區間測速實施路段:

目前警方將陸續在宜蘭縣、台北市、新北市、桃園市、苗栗縣、台中市、彰化縣、 高雄市、屏東縣、台東縣、花蓮縣..等37處路段設置區間測速。
以下區間測速資訊僅供參考,實際路段以交通警察局公布為準:

 PS: *苗栗兩路段夜間8時至隔日6時降為50公里

 

其中,北宜公路全路段被分成八路段實施區間測速,被網友喻為【區間測速大Boss】!

 

因應【區間測速】實施,目前已有區間測速超警示APP可以下載。不過,版主尚未實測過該APP,實際效果為何不得而知就是。

 

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

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

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

最低月銷僅2輛!這些車型有實力卻為何銷量最慘淡?_貨運

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

而且它的售價要比普通版本的polo要貴上一些。所以Cross polo是一個小型車的形象,但是價格更貴。因此它的接受度也就更低。同樣的價錢,我可以在買到一輛大眾的捷達。我為什麼不選大眾捷達呢。MG銳行9月銷量2498輛MG銳行在,外觀設計上也是十分的特別。

隨着九月份汽車銷量排行榜的出爐,許多車型的銷量數據也隨之浮出水面。我們發現那些銷量比較差的車型普遍都是一些比較的有個性的車型。那麼主要有哪些車型呢?我們一起來看一看。

雪佛蘭愛唯歐

九月銷量2輛

雪佛蘭愛唯歐其實是一款非常不錯的車型,它剛剛上市的時候主打的是個性與年輕,定位於80、90后。獨特的大燈機車式的儀錶。在這個價位的車型中都十分少見。可以說給這個沉悶的市場帶來了一股清風。不過隨着通用產品線的越來越密集。雪佛蘭愛唯歐的性價比優勢就不再那麼能夠凸顯。別克凱越經典、科魯茲以及最新的科沃茲都比雪佛蘭愛唯歐要更加的大,而且配置上更加的豐富。所以雪佛蘭愛唯歐的競爭優勢也就不那麼明顯了。改款愛唯歐在大燈造型上變得十分的中庸,搭配上這個個性的車身顯得有些不倫不類。可以說愛唯歐已經迷失了自己。

本田歌詩圖

九月銷量326輛

歌詩圖的推出可以說讓人眼前一亮,不過這款個性的coupe風格的SUV並沒能成功的打開市場。反而讓自己陷入了一個兩難的境地,作為SUV它沒有足夠高的視野以及實用性,而作為轎車他又顯得有些不倫不類。除了那些比較注重個性的人之外似乎很難有一個讓人購買歌詩圖的理由。相比較雅閣來說歌詩圖的行駛質感以及舒適性並不佔優勢,而雅閣更加大的優惠以及更加低廉的價格也使得人們沒有理由去選擇一台更加昂貴並且另類的歌詩圖。

標誌308S

九月銷量810輛

以前我們說到法系兩廂車就會想到冷門,這也和法系車獨特的設計以及獨特的個性理念有着密不可分的關係,而現在的標緻308s也基本上保持了法系車在設計以及製造上的一種理念,也就是獨特,308S也是一台非常獨特的車型,採用了三缸發動機,在外觀的設計上它也要更加的大膽和獨特,但是它個性的外觀並沒有受到廣大消費者的喜愛。並且在性價比以及空間方面308S相比較其它車型並不佔有優勢。因此308S並不是十分適合家用的一款車型,或者說它用來家用的話並沒有優勢。 所以他銷量不佳也就是十分順理成章的事情。

大眾Cross polo

9月銷量839輛

有人說大眾是一個十分精明的商家。它旗下的每一款車型銷量都不差,但是大眾的Cross polo就是一個返利。大眾的Cross polo是一個跨界車型。相比較普通的polo它有了車頂的行李架。也有了這個車身的黑色塑料包圍,

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

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

因此看起來更加的具有野性。但是相比較普通的polo它並沒有本質的區別。而且它的售價要比普通版本的polo要貴上一些。所以Cross polo是一個小型車的形象,但是價格更貴;因此它的接受度也就更低。同樣的價錢,我可以在買到一輛大眾的捷達。我為什麼不選大眾捷達呢?

MG銳行

9月銷量2498輛

MG銳行在,外觀設計上也是十分的特別。頗有幾分MG6的感覺。掀背式的車尾造型十分的有特點在如今的轎車中也是十分的流行,最早我們認識這類車型可能是奧迪的A7,寶馬的五系GT,不過MG銳行可以說是把這樣的造型設計帶到了一個比較低的價位。也算是為消費者造福,但是顯然這樣的設計在10萬元這個售價區間的接受度並不高,而MG銳行不那麼突出的性價比也是一個阻礙。

日產藍鳥

9月銷量6111輛

日產藍鳥和日產的軒逸是兩款姐妹車型。他們的設計不同,軒逸主打的是成熟穩重。藍鳥主打運動年輕,同在緊湊型轎車市場里兩款車型通過不同的定位相同的定價來提升日產品牌在緊湊型轎車中的份額。但是和軒逸的暢銷相比藍鳥的銷量可就不那麼好看了。沒有口碑的積累外觀也頗受爭議,藍鳥作為日產個性化的一個代表確實讓人嘆息,不過好在這樣的銷量也能夠勉強度日了。

豐田銳志

9月銷量892輛

豐田銳志是一款讓我們印象很深刻的車型。V6、后驅這些特性都讓我們十分喜愛,相比較銳志的外觀在前幾年來說還算是很不錯,但是空間是他最大的硬傷,外觀和如今的阿特茲蒙迪歐相比也不再算是吸引人,它並不算一款合格的運動型車。整個底盤調教的方向就是偏向於細膩、高級。和豐田的皇冠是同平台。所以它的設計初衷就不是為了運動,因此它應該是一款高級商務轎車,而並非是一款運動型車。

上面這些車型都有着十分鮮明的特點,而且他們大多數都在外觀設計上十分有特點,並且優點和缺點都十分明顯。比如豐田銳志的發動機運轉的精緻度、細膩度和靜謐性都十分討人喜歡,但是它的空間在同級別的競爭對手面前顯得太過於小,我們消費者對一輛汽車的期望是比較高的。一輛汽車承載了我們許許多多的需求。我們希望它各方面都能夠做到完美。因此一旦有一方面讓我們不夠滿意。我們可能就會因此而放棄這款車型。這也是上面這些車型賣不好的原因。好的產品能夠讓我們記住。但是只有均衡的產品才能夠行銷海外。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。