2020-04-30

[iOS 开发] iOS 开发从菜鸟到高手?听听他们怎么说

[iOS 开发] iOS 开发从菜鸟到高手?听听他们怎么说


不知不觉,做 iOS 开发也有一年多时间了,算是经历了从入门到初级的过程,最近也感到些许迷茫,不知道以后的路怎么走。下周马上就要加入一家新公司去独立开发一个项目了,希望接下来这一年能有不错的收获,交得出一份拿得出手的成绩单。趁这两天有空,找了些业内前辈们的经验分享,看看他们怎么说的,希望自己能静下心来,一步一个脚印走下去吧!

1. iOS开发如何快速成长?(叶孤城)

  • 勇于接受挑战,实现有难度的需求

“不管完成度如何,我在两个月后东拼西凑都给他弄出来了。”

  • 可以接触到新知识
  • 锻炼自学能力
  • 借鉴一些优秀的作品
  • 学习优秀的实现方案/第三方库
  • 自己摸索,独立解决问题,学会触类旁通,举一反三

  • 多读源码

    • 既要“走心”,又要“不求甚解”
    • 要看就看经典的
    • 最好是看和最近的工作相关的
  • **多看国外的 iOS 开发网站和 blog **

“第一手的开发资料永远都是英文的,而且以英语为母语的开发者学起新技术来有天然的优势。”

  • 学无止境

有句话叫技多不压身,编程本来就是一个更新换代非常快的工作.每年都有新的技术出现,我认为要成为一个出色的程序员只掌握一门语言肯定是不行的。

  • 打好基础
  • 研究一个自己感兴趣的领域
  • 学习一门自己感兴趣的语言

学习的圈子特别重要!!

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:761407670 进群密码‘博客’,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!

2. 成长为 iOS 大 V 的秘密(唐巧)

  • 巧哥的成就:
  • 从开始学习 iOS 开发半年后,就开始独立负责 iOS 端的开发工作。
  • 从 2013 年 1 月创建「iOS 开发」微信公众帐号,然后每周坚持更新,现在有超过 3 万 5 千的订阅量。

  • 从 2013 年底开始撰写《iOS 开发进阶》,2014 年底完成。另外我还写了一年多 「iOS 开发周报」。

  • 将公司的网络库,Key-Value 存储库开源,GitHub 上 Star 数上千。

  • 坚持写 iOS 技术博客,现在完成了超过 100 篇原创文章,很多发表在 InfoQ 和 《程序员》杂志上。

  • 入门:斯坦福的 iOS 开发视频课程

  • 寻找志同道合的朋友,一起交流、讨论、分享

  • 提高

  • 看 WWDC 视频

  • 做笔记

  • 读优秀 iOS 博客

  • 写作

  • 心得

  • 利用好碎片时间

“在我看来,当你做不好某一件事情时,时间通常是最大的借口。”

  • 提高工作的效率,使用番茄工作法,让自己能够在短时间内集中精力做一件事情
  • 写代码之前,先在纸上把逻辑写清楚
  • 平衡好时间和代码质量
  • 培养习惯

“不止是个人,组织的协作也应该培养习惯。”

  • 设立目标

“把大目标拆分成小的阶段性目标这一点很重要,它使得整体的时间安排是适当的,不会刚开始过紧或过松。另一方面,很一次完成小任务的满足感,可以适当让我们的大脑产生喜悦,最终使得任务更容易被搞定。”

  • 寻找成就感
  • 适度坚持

“总会有一些事情,你不那么容易找到目标和成就感。”

3. iOS开发如何提高(唐巧)

  • 阅读高质量的博客
  • 读经典书籍
  • 看 WWDC 视频
  • 看苹果的官方文档
  • 看优秀开源项目的代码
  • 多写代码,多思考
  • 多和同行交流
  • 乐于分享

4. 软件开发中的上帝模式与农民模式(唐巧)

  • 上帝模式的技巧: 写代码前,构思好整个应用的架构设计,如何进行类之间的组织和信息的传递。

“在软件开发书籍中,涉及上帝模式的图书也有很多,例如《设计模式》和《重构》,但是好的架构都是无法脱离实际业务的,所以大多数程序员都无法通过简单地看书就提高自己的上帝模式的能力,更多的提高方式是工作一段时间,有一些实际体会之后再看书,就能够理解书中的道理。”

  • 农民模式的技巧

    • 效率第一,保证自己的专注力,番茄工作法
    • 应该尽量采用「宽度优先搜索」的方式来完成任务,而不是「深度优先搜索」的方式
    • 尽量提升自己的代码输入效率
  • 提升上帝模式能力

    • 多分析一些优秀的开源软件的架构
    • 阅读一些相关的书籍,如《设计模式》,《重构》,《代码大全》等
    • 重构,结合自身的业务特点,多思考多讨论,培养出自己对于架构的一些心得
  • 提升农民模式效率

  • 番茄工作法

  • 时间记录

  • 平时多学习一些最新的 iOS 开发知识,减少知识盲区

  • 专注于自己的精力是否集中,如果觉得太累,就活动一下或者适当休息,不应该强迫自己 Coding

  • 警惕混搭模式

5. 王巍访谈:关于Swift学习和AppleWatch开发的一些建议(CocoaChina)

  • 先学习 Objective-C 还是 Swift?

“其实不论是 Objective-C 还是 Swift,现在的目的都是写 iOS 和 OSX 的 app,那么其实对于绝大多是情况来说,语言本身并不是非常重要,使用语言去和 Cocoa 以及 CocoaTouch 交互才是我们日常开发中最常用到的技能。Cocoa 的编程思想并没有随着语言的变化发生什么大改变,所以还是应该把对于框架的学习放在首位。”

  • 现在用 Objective-C 写,怎么为以后学 Swift 做铺垫呢?

“现在可能在工作中使用 Objective-C 的开发者还是占大多数,我的建议是在使用 Objective-C 的时候,也顺便可以“想象”一下如何用 Swift 更好地实现同样的事情。如果不是特别赶进度的话,甚至可以再用 Swift 真实地实现一遍。因为两种语言最大的区别就是 Swift 拥有更强的类型检查和安全性,所以如果能够特别关注这点的话,之后快速切换到新的语言去就不会有什么问题。”

  • 对于学习Swift的开发者,入门以后应该如何进一步提高?

可以尽快开始动手实践开发一些 app。给自己定一个目标,比如花上几天时间或者一周的时间用 Swift 做一个能上架的简单 app 之类的。这个 app 不需要有特别复杂的功能,可能就是一个简单的天气查询提醒,或者是展示附近好吃又便宜的餐饮店面。与简单地写个 demo 相比,实际做一个真正的 app 对能力的提升所在的层次是完全不同的,后者需要更多的全局考虑和综合能力。不少问题只有在实践中才会遇到,才会被解决,而对应的能力也才能被提升。所以入门之后进一步提升的最好的路子就是实践,然后在实践中再去学习没有掌握的剩下的东西。
另外要注意的是,因为现在 Swift 还很新,很多东西并没有现成的方案或者所谓的最佳实践。在遇到这样的情况时,最好询问下你身边的资深 iOS 或者 Objective-C 的开发者。因为 Swift 和 Objective-C 其实是共通的,很多经验是可以参照借鉴的。”

6. 曾宪华访谈:公司与个人参与iOS开源的心得(CocoaChina)

  • 参与开源的感受

“从我自己的体验来看,参与开源项目对于程序员来讲是一种高效、快速学习成长的方法,不仅如此,如果你是一个技术爱好者,参与开源项目你有可能找到自己的兴趣、自己的优势等等,进而从事自己喜欢的工作,那种感觉真的太爽了。”

  • 参与开源提升团队协作能力

“另外参与开源在提升团队协作能力上有着比较明显的作用,一个有用的Issue反馈、有效的交流以及热情的帮助都会让我们成长,从而运用到团队协作中去,那这个收获可见而知,不但让你在团队中突出,还能让你认识很多大神。”

  • 参与开源可以开阔视野,提升自身能力

“另外对于一些工作繁忙的程序员,平时忙于公司的项目,空余时间通过侧面的形式(参与开源),也是提升自己整体能力一个很不错的方式。”

  • 参与开源的乐趣

“参与开源的乐趣就是能把自己的优势或缺陷分享出去,并且会有人欣赏你、纠正你、谴责你。”

  • 行动起来

“一个成功的开源项目,仅有自己一个人往往是不够的,通过多人合作的模式,把各自优点发挥出来,共同去维护一个有价值的、可持续发展的开源项目,最后得到收获将远远大于付出。”

7.Limboy:自学 iOS 开发的一些经验(蘑菇街Limboy)

成长之路:基础->入门->进阶->高级

  • 每个阶段都要有相应的目标和学习方式、内容
  • 英语
  • 书籍
  • 视频
  • 练习
  • 博客,网站
  • 优秀源码
  • 官方文档,WWDC
  • 工具

“我觉得无论学习什么,「速成」的心态是最要不得的,这只会让自己变得浮躁,一知半解,整个过程也很难让自己的元学习能力得到提升。慢慢来,攻占一个城后,再去打下一个,这时心态也会平和许多。”

8.Zenny Chen访谈: iOS开发者应该关注Metal(CocoaChina)

  • iOS开发者应该如何规划自己的职业发展路线?除了iOS之外,是否需要学习其他方面的技术?

“这个问题问得很好。我工作快有10年了。而iOS职业开发也就刚做满3年,呵呵。其实我觉得如果大家想往技术方向发展,那么首先要做的还是把基础打好。把基础打好之后,能应付各种新的编程语言,各种处理器、各种操作系统平台。所以我建议大家在业余时间里把传统的大学里所学的科目再巩固好,比如操作系统、数据结构、数理逻辑、计算机体系结构、汇编语言、C语言、网络通信、数据库。此外,大家也可以再熟悉一下HTML5相关技术,毕竟iOS所涉及的大多数都是移动互联网领域,所以有点HTML5知识的话会更好些。如果自己感觉C语言学得还不咋样可以再巩固它。C语言就是计算机编程领域里的数学,是所有类C编程语言的鼻祖语言,而且从TIOBE排名上大家也能看到,它目前一直处于第一位。另外,Objective-C完美无缝地兼容C语言,就从这点上来说,C语言仍然是十分重要的。

C、Objective-C与Swift的关系是:Swift是对Objective-C的封装,尽管这封装得改动很大,以至于你确实看不出它仍然是类C 语言;而Objective-C则是对C语言的封装,在C语言的基础上又添加了面向对象以及反射动态特性。所以,学好了C对于iOS开发来说非常有帮助。

上述主要是讲iOS职业技术开发者如何能进一步提升技术能力。其实归根结底,就是把基础打好,然后可以尝试去专某一更专业的领域,比如通信领域、3D图形领域、图像识别领域等。因为大凡做iOS的基本都是在应用层上捣鼓,应用层老实说做个一年两年能基本掌握,再继续下去对技术提升不大。

有些iOS开发者想要提升自己在公司的地位,我觉得很大程度上取决于自己对所在公司的核心业务的了解情况。对于中小企业,产品设计人员以及策划不可能把产品描述得很细,有不少地方需要开发者对设计意图做思维扩展。如果你对自己公司的企业文化、工作流程、核心业务逻辑都能很好把握的话,就能够做出超出期望的产品,再加上好好处理人际关系,要提升地位也不会是很困难的事情。

当然,我碰到比较多的还是很多年轻的开发者对未来感到迷茫,不知道今后的路该怎么走。所以,我认为对于那些开发者自己先把心沉静下来,然后把基础打好,然后思考自己今后的技术走向。毕竟,iOS开发在很长一段时间以内都将是热门的技术岗位。

要想向更高的职位发展,除了技术之外,我认为还要有对产品的把控、甚至市场新动向的嗅觉。既然已经在这个行业了就必须学会如何不断学习,快速应变市场的新热 点。目前app开发处于快速发展变化的移动互联网的中心,开发者有机会做出引领潮流甚至改变世界的作品,这些经历本身就是宝贵的财富,只要打好基础,做足 准备,抓住机遇,未来的前途一定是光明的。”

9.我的iOS成长之路-3-iOS开发个人提升(破船之家)

  • 饱览群书:高质量,英文书籍,博文,WWDC,斯坦福公开课,github,stackoverflow
  • 跟着项目一起成长
  • 与同行交流
  • 做一些分享

10.iOS 高级工程师是怎么进阶的?(知乎)

11.学习的圈子特别重要!!

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:761407670 进群密码‘博客’,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!


Flutter Weekly Issue 53

Flutter Weekly Issue 53


插件

  1. left-scroll-actions

    A useful left scroll actions widget like WeChat.一款仿微信效果的 Flutter 左滑菜单插件。现在支持iOS的展开与弹性效果。

  2. flutter-screen-scaler

    A package to resize your widgets according to the screen size with the use of percentages.

  3. string-scanner

    A class for parsing strings using a sequence of patterns.

  4. dart-class-generator

    A Flutter that can generate Dart classes. Runs on Android, Windows and Web.

  5. r-scan

    📷🖨Flutter二维码&条形码扫描插件,支持相机、文件、链接、Uint8List类型扫描

  6. barrage-flutter

    This is a barrage Engine for flutter.Flutter弹幕库

  7. flutter-playout

    Audio & Video player in Flutter. This plugin provides audio/video playback with background audio support and lock screen controls for both iOS & Android. Also provides player events such as onPlay, onPause, onTime etc.

  8. FlutterTencentImPlugin

    腾讯即时通讯(IM),Flutter插件,同时支持 Android 和 iOS

  9. flutter-icons

    Customizable Icons for Flutter

  10. azlistview

    Flutter 城市列表,联系人列表,索引&悬停。Flutter CityList View, ContactList View, Index & Hover.

  11. Flutter-UI-Kits

    This project contains various inspired UI kits purely coded in Flutter framework.

  12. simple-auth

    The Simplest way to Authenticate in Flutter

  13. dson

    dart library which converts Dart Objects into their JSON representation

  14. fresh

    A dio interceptor for built-in token refresh.

  15. dart-tags

    ID3 Tag parser written on the pure dart language.

  16. FlutterToast

    Android and iOS Toast Library for Flutter

  17. flutter-facebook-login

    A Flutter plugin for allowing users to authenticate with native Android & iOS Facebook login SDKs.

  18. http-interceptor

    This is a plugin that lets you intercept the different requests and responses from Dart's http package. You can use to add headers, modify query params, or print a log of the response.

Quick Reference

  1. flutter-face-detection

    This is a Flutter plugin for real-time, on-device, offline face & eye detection.

  2. catcher

    Flutter error catching & handling plugin

  3. flutter-mlkit

    A Flutter plugin to use the Firebase ML Kit.

  4. amap-map-fluttify

    高德地图 地图组件 Flutter插件

  5. qrcode-scanner

    A Flutter plugin 🛠 to scanning. Ready for Android 🚀

  6. flip-box-bar

    A 3D Bottom Navigation Bar in Flutter

  7. geolocation

    Flutter geolocation plugin for Android and iOS.

  8. flutter-nfc-reader

    A new flutter plugin to help developers looking to use internal hardware inside iOS or Android devices for reading and writing NFC tags.

  9. flutter-tts

    A flutter text to speech plugin (Swift,Java)

  10. flutter-socket-io

    Socket IO supprt for flutter. Looking for contributors Swift and Java.

App

  1. flutter-showcase

    A simple, fast and easy way to share you flutter project or mockups with the world

  2. listen-poetry-app

    诗词吧APP,一个集 诗词/诗人推荐、搜索、简介、赏析、朗读(下个版本) 于一体的诗词兴趣 APP

  3. opengit-flutter

    OpenGit基于Flutter的Github客户端,支持Android和iOS。项目中涉及到BloC、Redux、国际化、多主题以及Github相关信息的查看等。

示例

  1. flutter-douyin-demo

    This is a Flutter project to copy Dou Yin (which named Tik Tok overseas). 这是一个利用Flutter复制抖音(海外叫做TikTok)的小项目。

工具

  1. flr-vscode-extension

    Flr(Flutter-R) Extension: A Flutter Resource Manager VSCode Extension

  2. flr-as-plugin

    Flr(Flutter-R) Plugin: A Flutter Resource Manager Android Studio Plugin

  3. pubspec-version

    A CLI tool to get/set/bump the version key in pubspec.yaml.

原文地址:https://flutterweekly.dev/flutter-weekly-issue-53/
版权声明:禁止一切形式的转载-禁止商用-禁止衍生
公众号:Android开发技术周刊


Android 视图动画

Android 视图动画


一、视图动画标签

0.概述

视图动画有5中类型组成:
alpha:渐变透明度
scale:渐变尺寸伸缩
translate:画面变换位置移动
rotate:画面转移旋转移动
set:定义动画集

1.scale标签

scale_anim.

<?

pivotX有三种数值:

150 直接数字,则是以控件为原点坐标的xy的坐标值(150,150),以目标控件为原点

150% 百分比的,是以控件为原点坐标的,为控件的宽度的150%的坐标,150%那就是控件宽度的150%

150%p 上面同理,但是以父控件的150%

java代码

 startAnimBtn.setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    //装载动画 R.anim.scale_anim 为动画位置    Animation scaleAnimation=AnimationUtils.loadAnimation(mContext,R.anim.scale_anim);    //启动动画    scaleTV.startAnimation(scaleAnimation);   }  });

效果

scale.gif

2.共同属性

所有动画都继承自Animation类,所以有一些共同的属性。

android:duration="3000" //动画持续时间,毫秒单位android:fillAfter="true" //true动画结束,保持控件结束时的状态android:fillBefore="true"//true动画结束,保持控件最初始状态android:repeatCount="3" //动画重复次数,infinite表示无限循环android:repeatMode="restart" //重复的类型,restart表示从头开始,reverse表示倒序回放android:interpolator="@android:interpolator/accelerate_cubic" //插值器,控制速度等

看看回放和倒序回放
倒序回放:

android:repeatCount="3"android:repeatMode="reverse"

倒序回放.gif

回放:

android:repeatCount="3"android:repeatMode="restart"

回放.gif

3.alpha标签

<alpha android:duration="3000" //持续时间	android:fromAlpha="0.1" //初始透明度	android:toAlpha="1"/> //最大透明度 数值在0.0~1.0之间

效果:

透明度.gif

4.rotate标签

<alpha	android:fromAlpha="0.01" //初始角度	android:toAlpha="1"/> //旋转角度 取值范围可以为负值,为逆时针,正值为顺时针

效果:

旋转.gif

5.translate标签

 <translate  android:fromXDelta="50" //以控件为原坐标,x轴加50 为起始X轴  android:fromYDelta="50" //以控件为原坐标,y轴加50 为起始y轴  android:toXDelta="400" //目标x轴  android:toYDelta="400" /> //目标y轴

效果:

位移.gif

7.set标签

<?

效果:

完整动画.gif

二、视图动画代码实现

0.概述

这些标签,都对应一个类,但他们都是派生自Animation类。

scaleScaleAnimation
alphaAlphaAnimation
rotateRotateAnimation
translateTranslateAnimation
setAetAnimation

1.ScaleAnimation

四个构造方法来加载scale动画

ScaleAnimation(Context context, AttributeSet attrs) ScaleAnimation(float fromX, float toX, float fromY, float toY) ScaleAnimation(float fromX, float toX, float fromY, float toY,   float pivotX, float pivotY) ScaleAnimation(float fromX, float toX, float fromY, float toY,   int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) 

ScaleAnimation(
float fromX, //初始x轴的缩放

float toX, //目标缩放

float fromY, //初始y轴缩放

float toY, //目标y轴缩放

int pivotXType, float pivotXValue, //以原坐标为原点,x轴的起始点

int pivotYType, float pivotYValue) //以原坐标为原点,y轴的起始点

pivotXType的类型有:

RELATIVE_TO_SELF 百分比,相对自身百分比 50%

RELATIVE_TO_PARENT 百分比,相对父控件百分比 50%p

ABSOLUTE 具体数值 比如 50

2.AlphaAnimation

AlphaAnimation(Context context, AttributeSet attrs) AlphaAnimation(float fromAlpha, float toAlpha) 

AlphaAnimation(
float fromAlpha, //初始透明度

float toAlpha) //目标透明度

3.RotateAnimation

RotateAnimation(Context context, AttributeSet attrs) RotateAnimation(float fromDegrees, float toDegrees) RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,   int pivotYType, float pivotYValue) 

RotateAnimation(
float fromDegrees, //初始角度

float toDegrees, //目标角度

int pivotXType, float pivotXValue,
int pivotYType, float pivotYValue)

4.TranslateAnimation

TranslateAnimation(Context context, AttributeSet attrs) TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)  TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,   int fromYType, float fromYValue, int toYType, float toYValue)  

TranslateAnimation(
int fromXType, float fromXValue, //起始x轴坐标

int toXType, float toXValue, //目标x轴坐标

int fromYType, float fromYValue, //起始y轴坐标

int toYType, float toYValue) //目标y轴坐标

5.AnimationSet

AnimationSet(Context context, AttributeSet attrs) AnimationSet(boolean shareInterpolator) //true 共用一个插值器,false 各自定义插值器

都是继承自Animation,有这些共同属性

animationSet1.setDuration(3000); //动画时长animationSet1.scaleCurrentDuration(4.0f); //当前动画时间animationSet1.setFillAfter(true); //true动画结束,保持控件结束时的状态animationSet1.setFillBefore(true); //true动画结束,保持控件最初始状态animationSet1.setRepeatMode(Animation.RESTART); //循环模式animationSet1.setStartOffset(1000); //在什么时间停止动画animationSet1.setStartTime(500); //在什么时间开始动画animationSet1.setRepeatCount(5); //循环次数animationSet1.setFillEnabled(true); //true动画结束,保持控件结束时的状态

装载所有动画效果

 		ScaleAnimation scaleAnimation1 = new ScaleAnimation(      0.0f,      1.4f,      0.0f,      1.4f,      Animation.RELATIVE_TO_SELF, 0.5f,      Animation.RELATIVE_TO_SELF, 0.5f);    AlphaAnimation alphaAnimation1=new AlphaAnimation(0.1f,0.5f);    RotateAnimation rotateAnimation1=new RotateAnimation(0.1f,0.1f);    TranslateAnimation translateAnimation1=new TranslateAnimation(      Animation.ABSOLUTE,      50,      Animation.ABSOLUTE,      50);    AnimationSet animationSet1=new AnimationSet(true); //装载    animationSet1.addAnimation(scaleAnimation1);    animationSet1.addAnimation(alphaAnimation1);    animationSet1.addAnimation(rotateAnimation1);    animationSet1.addAnimation(translateAnimation1);    animationSet1.setDuration(3000);    animationSet1.scaleCurrentDuration(4.0f);    animationSet1.setFillAfter(true);    animationSet1.setFillBefore(true);    animationSet1.setRepeatMode(Animation.RESTART);    animationSet1.setStartOffset(1000);    animationSet1.setStartTime(500);    animationSet1.setRepeatCount(5);    animationSet1.setFillEnabled(true);

6.Animation

animationSet1.cancel(); //取消动画animationSet1.reset(); //将控件重置到初始化状态animationSet1.setAnimationListener(AnimationListener listener); //设置监听

监听,利用监听可以实现动画的连续效果,比如,先实现缩放,再实现位移

 animationSet1.setAnimationListener(new Animation.AnimationListener() {     @Override     public void onAnimationStart(Animation animation) {      //动画开始     }     @Override     public void onAnimationEnd(Animation animation) {      //动画结束     }     @Override     public void onAnimationRepeat(Animation animation) {      //动画结束     }    });

三、基础插值器

0.概述

控制动画变化速率的值,就叫插值器,也叫加速器。有Interpolator类来决定。

使用方法
android:interpolator="@android:anim/accelerate_interpolator"

<set 

在java代码中使用;
animationSet1.setInterpolator(new AccelerateInterpolator());

1.系统插值器

系统已经定义了一些常见的插值器

AccelerateDecelerateInterpolator@android:anim/accelerate_decelerate_interpolator先加速,后减速
AccelerateInterpolator@android:anim/accelerate_interpolator开始慢,后一直加速
DecelerateInterpolator@android:anim/decelerate_interpolator开始一瞬间加到最大,后慢慢减慢
LinearInterpolator@android:anim/linear_interpolator匀速加速器
BounceInterpolator@android:anim/bounce_interpolator模拟自由落体回弹的效果
AnticipateInterpolator@android:anim/anticipate_interpolator反方向效果一段时间,再执行正常动画,如,旋转。先反旋转一段距离
OvershootInterpolator@android:anim/overshoot_interpolator动画结束之后,再执行一段时间
AnticipateOvershootInterpolator@android:anim/anticipate_overshoot_interpolator开始时,反方向效果一段时间,结束时,超过效果时间一段时间
CycleInterpolator(1)@android:anim/cycle_interpolator动画特定循环播放的次数,速率沿正弦曲线变化

四、动画示例

1.镜头由远及近

控件

<ImageView  android:id="@+id/img"  android:src="@drawable/ali"  android:layout_width="match_parent"  android:layout_height="match_parent"/>

java代码

    ScaleAnimation scaleAnimation=new ScaleAnimation(      0.5f,      1.2f,      0.5f,      1.2f,      Animation.RELATIVE_TO_SELF,0.5f,      Animation.RELATIVE_TO_SELF,0.5f);    scaleAnimation.setFillAfter(true);    scaleAnimation.setInterpolator(new AccelerateInterpolator());    scaleAnimation.setDuration(6000);    imgIV.startAnimation(scaleAnimation);

效果:

由远及近.gif

2.加载框效果

 <ImageView  android:id="@+id/load"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_gravity="center"  android:layout_marginTop="30dp"  android:src="@drawable/load" />
  RotateAnimation rotateAnimation=new RotateAnimation(      0,      360,      Animation.RELATIVE_TO_SELF,0.5f,      Animation.RELATIVE_TO_SELF,0.5f);    rotateAnimation.setFillAfter(true);    rotateAnimation.setRepeatCount(Animation.INFINITE); //无限循环    rotateAnimation.setInterpolator(new LinearInterpolator()); //匀速    rotateAnimation.setDuration(2000);    loadIV.startAnimation(rotateAnimation);

效果:

加载.gif

编程中我们会遇到多少挫折?表放弃,沙漠尽头必是绿洲。


Async,Await 深入源码解析

Async,Await 深入源码解析


1.同步与异步

   假设存在

   IO事件A:请求网络资源 (完成耗时5s)

   IO事件B:查询数据库 (完成耗时5s)

   情况一:线程1工人在发起A请求后,一直阻塞等待,在A响应返回结果后再接着处理事件B,那总共需要耗时>10s.

   情况二:线程1工人在发起A请求后,马上返回发起B请求然后返回,5s后事件A响应返回,接着事件B响应返回,那总共需要耗时<10s.

   情况一就是同步的概念,而情况二就是异步的概念。细节会有所不同,但大致上可以这样理解。然而并不是所有情况适用异步,下面将会解释。

2.异步运行的顺序

   c#中的异步关键词是async与await,常常结合Task使用,如下面实例,看看它执行的情况

 static async Task Main(string[] args)  {   Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:MainStart"); //标记1   await SayHi();   Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:MainEnd"); //标记4  }  static async Task SayHi()  {   Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:SayHiStart"); //标记2   await Task.Delay(1000);   Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:SayHiEnd"); //标记3  }

 

结果:

1:MainStart
1:SayHiStart
5:SayHiEnd
5:MainEnd

 

c#7.1后的版本都支持异步main方法,程序执行的状况 

线程1->标记1,

线程1->标记2,

线程5->标记3

线程5->标记4

执行顺序如预期,而需要关注的是线程在执行期间的切换,在线程1执行完标记2后就已经返回,接着由线程5接管了后面代码逻辑的执行,那到底为什么会发生这样的情况?

答案是:编译器会自动地替我们完成了大量了不起的工作,下面接着来看看。

 

3.生成骨架与状态机

 编译器在遇到await关键字会自动构建骨架与生成状态机,按照以上例子来看看编译器做的工作有那些。

[DebuggerStepThrough]private static void <Main>(string[] args){ Main(args).GetAwaiter().GetResult();}[AsyncStateMachine((Type) typeof(<Main>d__0)), DebuggerStepThrough]private static Task Main(string[] args){ <Main>d__0 stateMachine = new <Main>d__0 {  args = args,  <>t__builder = AsyncTaskMethodBuilder.Create(),  <>1__state = -1 }; stateMachine.<>t__builder.Start<<Main>d__0>(ref stateMachine); return stateMachine.<>t__builder.get_Task();}[AsyncStateMachine((Type) typeof(<SayHi>d__1)), DebuggerStepThrough]private static Task SayHi(){ <SayHi>d__1 stateMachine = new <SayHi>d__1 {  <>t__builder = AsyncTaskMethodBuilder.Create(), //如果返回的是void builder为AsyncVoidMethodBuilder  <>1__state = -1  //状态初始化为-1 }; stateMachine.<>t__builder.Start<<SayHi>d__1>(ref stateMachine); //开始执行 传入状态机的引用 return stateMachine.<>t__builder.get_Task(); //返回结果}

1.编译器会自动生成void mian程序入口方法,它会调用async Task main方法。(所以说c#7.1支持异步main方法,其实只是编译器做了一点小工作)

2.main方法里的输出内容与调用SayHi方法代码消失了,取而代之的是编译器生成了骨架方法,初始化 <Main>d__0 状态机,把状态机的状态字段<>1__state

初始化为-1,builder为AsyncTaskMethodBuilder实例,接着调用builder的Start方法。

3.SayHi方法同2

接着看看AsyncTaskMethodBuilder的Start方法

[DebuggerStepThrough]public static void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine: IAsyncStateMachine{ if (((TStateMachine) stateMachine) == null) {  ThrowHelper.ThrowArgumentNullException(ExceptionArgument.stateMachine); } Thread currentThread = Thread.CurrentThread; Thread thread2 = currentThread; ExecutionContext context2 = currentThread._executionContext; SynchronizationContext context3 = currentThread._synchronizationContext; try {  stateMachine.MoveNext(); //调用了状态机的MoveNext方法 } finally {  SynchronizationContext context4 = context3;  Thread thread3 = thread2;  if (!ReferenceEquals(context4, thread3._synchronizationContext))  {   thread3._synchronizationContext = context4;  }  ExecutionContext contextToRestore = context2;  ExecutionContext currentContext = thread3._executionContext;  if (!ReferenceEquals(contextToRestore, currentContext))  {   ExecutionContext.RestoreChangedContextToThread(thread3, contextToRestore, currentContext);  } }}

Start方法调用了状态机的MoveNext方法,是不是很熟悉?接下来看看状态机长什么样子。

[CompilerGenerated]private sealed class <Main>d__0 : IAsyncStateMachine{ // Fields public int <>1__state; public AsyncTaskMethodBuilder <>t__builder; public string[] args; private TaskAwaiter <>u__1; // Methods private void MoveNext() {  int num = this.<>1__state;  try  {   TaskAwaiter awaiter;   if (num == 0)   {    awaiter = this.<>u__1;    this.<>u__1 = new TaskAwaiter();    this.<>1__state = num = -1;    goto TR_0004;   }   else //1: <>1_state初始值为-1,所以先进到该分支,由线程1执行   {    Console.WriteLine($"{(int) Thread.get_CurrentThread().ManagedThreadId}:MainStart"); //标记1 //线程1执行 所以输出 1:MainStart    awaiter = Program.SayHi().GetAwaiter(); //重点:获取Taskd GetAwaiter方法返回TaskAwaiter    if (awaiter.IsCompleted) //重点:判断任务是否已经完成     {     goto TR_0004; //SayHi方法是延时任务,所以正常情况下不会跳进这里    }    else    {     this.<>1__state = num = 0; //赋值状态0     this.<>u__1 = awaiter;      Program.<Main>d__0 stateMachine = this;     this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter, Program.<Main>d__0>(ref awaiter, ref stateMachine); //重点:把TaskAwaiter与该状态机,线程1执行到这返回   
}
}
     return;
TR_0004:
awaiter.GetResult(); //重点:获取结果 由线程1执行或延时任务不定线程执行
Console.WriteLine($"{(int) Thread.get_CurrentThread().ManagedThreadId}:MainEnd"); //标记4 所以输出 5:MainEnd

this.<>1__state = -2; this.<>t__builder.SetResult();//设置结果
}
catch (Exception exception)
{
this.<>1__state = -2;
this.<>t__builder.SetException(exception); //设置异常
}
}
[DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } }

上面我圈了重点的是关于Task类型能实现async await的关键操作, 

1.线程1执行调用Task实例的GetAwaiter方法返回TaskAwaiter实例。

2.判断TaskAwaiter实例的IsCompleted属性是否完成,如果已完成,跳转到TR_0004,否则执行到AwaitUnsafeOnCompleted方法,线程1结束返回。

我们继续来看看AwaitUnsafeOnCompleted方法,没反编译出来,所以我们来看看与它类似的AwaitOnCompleted方法( AwaitUnsafeOnCompleted实际上会调用UnsafeOnCompleted方法)

public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter: INotifyCompletion where TStateMachine: IAsyncStateMachine{ try {  awaiter.OnCompleted(this.GetStateMachineBox<TStateMachine>(ref stateMachine).MoveNextAction); } catch (Exception exception1) {  Task.ThrowAsync(exception1, null); }}

 

看到这里是不是豁然开朗了

1.注册TaskAwaiter实例完成任务的回调方法,等任务完成后将会调用状态机的MoveNext方法,由上篇文章Task的启动方式知道后面的操作将会交由线程池的线程处理。所以标记3跟标记4将会在空闲的线程上执行。

2.<>1__state为0,跳到TR_0004执行,调用TaskAwaiter实例的GetResult()方法,执行await后面的代码,返回结果。

SayHi方法同上。

结论

编译器遇到await后会自动构建骨架与状态机,把await后面的代码挪到任务完成的后面继续执行。主线程第一次调用MoveNext方法时,如果任务已经完成会直接执行后面的操作,否则直接返回,不阻塞主线程的运行。后面的流程

将交由线程池来调度完成。

回到文章开头的问题,什么情况下不适用异步?

可以看出来,使用异步编译器会生成大量额外的操作,而不耗时或者CPU密集型工作使用异步就是添堵。

 

思考

是不是只有Task才能用async与await?

下一篇我将来探讨一下这个问题,感兴趣的小伙伴可以关注留意后续更新

有说得不对的地方欢迎大神指正,欢迎讨论,共同进步

 


在WebApi 中使用AutoFac

在WebApi 中使用AutoFac


参考文档

https://www.cnblogs.com/htsboke/p/10956807.html

https://www.cnblogs.com/lenmom/p/8510572.html

 

在WebApi项目中使用AutoFac,结构如下:

首先在Api项目当中引用AutoFac包,如下图所示:

 

仓储类:

 1  public interface IUsersRepository 2  { 3   int GetUserIsExists(UsersEntity criteria); 4  5  } 6  7  8  public class UsersRepository : IUsersRepository 9  {10   Logger log = LogManager.GetLogger("UsersRepository");11 12   /// <summary>13   /// 获取用户是否存在14   /// </summary>15   /// <param name="criteria"></param>16   /// <returns></returns>17   public int GetUserIsExists(UsersEntity criteria)18   {19    string sql = "。。。。";20    try21    {22     //查询sql代码,此处省略。。。。    
}28 catch (Exception ex)29 {30 log.Fatal(ex, "获取用户是否存在异常:{0},SQL:{1}", ex.Message, sql);31 return 0;32 }33 }34 }

服务类:

 1  //接口 
public interface IUsersService 4 { 5 int GetUserIsExists(UsersEntity criteria); 6 7 } 8 10 //实现类11 public class UsersService : IUsersService12 {13 private readonly IUsersRepository _usersrepository; 14 public UsersService(IUsersRepository usersrepository) //通过构造函数注入15 {16 _usersrepository = usersrepository;17 }18 19 /// <summary>20 /// 获取用户是否存在21 /// </summary>22 /// <param name="criteria"></param>23 /// <returns></returns>24 public int GetUserIsExists(UsersEntity criteria)25 {26 return _usersrepository.GetUserIsExists(criteria);27 }28 }

在Api接口项目中创建一个AutoFac工具类:AutofacUtil.cs   

 1  public class AutofacUtil 2  { 3   private static IContainer _container; 4  5   public static void ConfigureContainer() 6   { 7    #region AutoFac IOC容器 8  9    var builder = new ContainerBuilder();10 11    try12    {13     //builder.RegisterControllers(Assembly.GetCallingAssembly()); //注册mvc控制器 需要引用package Autofac.Mvc14 15     //builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired(); //支持Api控制器属性注入16     builder.RegisterApiControllers(Assembly.GetCallingAssembly()); //注册所有api控制器 构造函数注入 需要引用package Autofac.WebApi17 18     //注册程序集19     #region Service20     var assemblysServices = Assembly.Load("WebApi.Service");21     builder.RegisterAssemblyTypes(assemblysServices)22     .AsImplementedInterfaces()23     .InstancePerDependency();24     

.Net平台GC VS JVM垃圾回收

.Net平台GC VS JVM垃圾回收


前言

不知道你平时是否关注程序内存使用情况,我是关注的比较少,正好借着优化本地一个程序的空对比了一下.Net平台垃圾回收和jvm垃圾回收,顺便用dotMemory看了程序运行后的内存快照,生成内存快照后,妈妈再也不担心我优化程序找不到方向了。

.Net平台垃圾回收

内存优化

凭空想象这些概念多少会索然无味,下图是我我基于本地的一个程序生成的内存快照,使用jetbrains推出的dotMemory工具生成。

生成内存快照

QQ截图20200422180141.png
程序运行时可以通过右上角的Get SnapShot按钮生成内存快照,内存快照里可以看到具体的对象、消耗内存的情况,比如说一些大的字符串对象,重复的大量的字符串对象, 那么从上面这张图上都能看到哪些关键字呢?
什么是Heap generation1和Heap greneration2呢?
什么是Allocated呢?

什么是GC

GC (Garbage Collection)如其名,就是垃圾收集,当然这里仅就内存而言。Garbage Collector(垃圾收集器,在不至于混淆的情况下也成为GC)以应用程序的root为基础,遍历应用程序在托管堆(Managed Heap)上动态分配的所有对象,通过识别它们是否被引用来确定哪些对象是已经死亡的、哪些仍需要被使用。已经不再被应用程序的root或者别的对象所引用的对象就是已经死亡对象,即所谓的垃圾,需要被回收。这就是GC工作的原理。为了实现这个原理,GC有多种算法。比较常见的算法有Reference Counting,Mark Sweep,Copy Collection等等。目前主流的虚拟系统.NET CLR,JVM都是采用的Mark Sweep算法。

Mark-Compact 标记压缩算法

简单地把.NET的GC算法看作Mark-Compact算法。阶段1: Mark-Sweep 标记清除阶段,先假设heap中所有对象都可以回收,然后找出不能回收的对象,给这些对象打上标记,最后heap中没有打标记的对象都是可以被回收的;阶段2: Compact 压缩阶段,对象回收之后heap内存空间变得不连续,在heap中移动这些对象,使他们重新从heap基地址开始连续排列,类似于磁盘空间的碎片整理。



Heap内存经过回收、压缩之后,可以继续采用前面的heap内存分配方法,即仅用一个指针记录heap分配的起始地址就可以。主要处理步骤:将线程挂起→确定roots→创建reachable objects graph→对象回收→heap压缩→指针修复。可以这样理解roots:heap中对象的引用关系错综复杂(交叉引用、循环引用),形成复杂的graph,roots是CLR在heap之外可以找到的各种入口点。
GC搜索roots的地方包括全局对象、静态变量、局部对象、函数调用参数、当前CPU寄存器中的对象指针(还有finalization queue)等。主要可以归为2种类型:已经初始化了的静态变量、线程仍在使用的对象(stack+CPU register) 。 Reachable objects:指根据对象引用关系,从roots出发可以到达的对象。例如当前执行函数的局部变量对象A是一个root object,他的成员变量引用了对象B,则B是一个reachable object。从roots出发可以创建reachable objects graph,剩余对象即为unreachable,可以被回收。

指针修复是因为compact过程移动了heap对象,对象地址发生变化,需要修复所有引用指针,包括stack、CPU register中的指针以及heap中其他对象的引用指针。Debug和release执行模式之间稍有区别,release模式下后续代码没有引用的对象是unreachable的,而debug模式下需要等到当前函数执行完毕,这些对象才会成为unreachable,目的是为了调试时跟踪局部对象的内容。传给了COM+的托管对象也会成为root,并且具有一个引用计数器以兼容COM+的内存管理机制,引用计数器为0时,这些对象才可能成为被回收对象。Pinned objects指分配之后不能移动位置的对象,例如传递给非托管代码的对象(或者使用了fixed关键字),GC在指针修复时无法修改非托管代码中的引用指针,因此将这些对象移动将发生异常。pinned objects会导致heap出现碎片,但大部分情况来说传给非托管代码的对象应当在GC时能够被回收掉。


垃圾回收之三个阶段

PhaseInGarbageCollection.png

  • Marking Phase:在标记阶段会创建所有活动对象的列表。 这是通过遵循所有根对象的引用来完成的。 不在活动对象列表中的所有对象都可能从堆内存中删除。
  • Relocating Phase:所有活动对象列表中所有对象的引用在重定位阶段进行更新,以便它们指向在压缩阶段将对象重定位到的新位置。
  • Compacting Phase:随着释放死亡对象占用的空间并移动剩余的活动对象,堆会在压缩阶段被压缩。 垃圾回收后剩余的所有活动对象均按其原始顺序移至堆内存的较旧端。

垃圾回收之Genearation - 分代

堆内存在回收过程中不是一次性回收所有,而是分为3代,目前也支持3代,根据上面的截图可以看出来。因此可以在垃圾回收期间适当地处理具有不同生存期的各种对象。 取决于项目的大小,每一代的内存将由公共语言运行时(CLR)给出。 在内部,Optimization Engine将调用Collection Means方法来选择哪些对象将进入第1代或第2代。


HeapGenerationInGarbageCollection.png

  • Generation 0:所有短期对象(例如临时变量)都包含在堆内存的第0代中。 除非它们是大对象,否则所有新分配的对象也是隐式的第0代对象。 通常,垃圾回收的频率在第0代中最高。
  • Generation 1:如果运行在垃圾回收中未释放的第0代对象占用的空间,则这些对象将移至第1代。这一代中的对象是第0代中的短期对象和第2代中的长期对象之间的一种缓冲区对象。
  • Generation 2:如果某个第1代对象占用的空间未在下一次垃圾回收运行中释放,则这些对象将移至第2代。第2代对象的生存期很长,例如静态对象,因为它们整个都保留在堆内存中 处理持续时间。

GC给我们带来的优势

  • 垃圾回收使用3个代的概念成功的在托管堆上有效的分配对象内存。
  • 不再需要手动释放内存,GC会在不需要时自动释放内存空间。
  • 垃圾回收可以安全地处理内存分配,因此没有对象会错误地使用另一个对象的内容。
  • 新创建的对象的构造函数不必初始化所有数据字段,因为垃圾回收会清除以前释放的对象的内存。

非托管堆

说了半天都在说托管堆,那么非托管堆呢?垃圾回收是不知道什么时候去处理非托管堆资源,比如文件句柄,网络连接、数据库连接。以下两种方式用来处理非托管堆垃圾回收。

  1. 在定义类时声明析构函数。
  2. 在定义类时实现IDisposable接口并实现Dispose函数, 实现接口有在程序中有两种处理方法,使用using关键字,推荐使用, 再就是在finally中显式调用Dispose函数。

附录GC常用函数

返回指定对象的当前代数public static int GetGeneration(Object);检索当前认为要分配的字节数。 一个参数,指示此方法是否可以等待较短间隔再返回,以便系统回收垃圾和终结对象public static long GetTotalMemory (bool forceFullCollection);返回已经对对象的指定代进行的垃圾回收次数。public static int CollectionCount (int generation);获取垃圾回收的内存信息public static GCMemoryInfo GetGCMemoryInfo ();强制对所有代进行即时垃圾回收。public static void Collect ();

jvm垃圾回收

好吧,说到这里还没提出来jvm垃圾回收,如果你已经了解了jvm垃圾回收,从上面的垃圾回收算法和分代回收来看,.Net平台和jvm在垃圾回收这块设计思路是一致的,两者的垃圾回收算法都包含:标记清除算法、复制算法、标记整理算法、分代收集算法。
** 当前商业虚拟机算法都使用分代收集算法,jvm根据对象的存活周期把内存划分为:
年轻代、老年代、永久代。

新生代(Young generation)

绝大多数最新被创建的对象会被分配到这里,由于大部分对象在创建后会很快变得不可达,所以很多对象被创建在新生代,然后消失。对象从这个区域消失的过程我们称之为 minor GC。
新生代 中存在一个Eden区和两个Survivor区.新对象会首先分配在Eden中(如果新对象过大,会直接分配在老年代中)。在GC中,Eden中的对象会被移动到Survivor中,直至对象满足一定的年纪(定义为熬过GC的次数),会被移动到老年代。
可以设置新生代和老年代的相对大小。这种方式的优点是新生代大小会随着整个堆大小动态扩展。参数 -XX:NewRatio 设置老年代与新生代的比例。例如 -XX:NewRatio=8 指定 老年代/新生代 为8/1. 老年代 占堆大小的 7/8 ,新生代 占堆大小的 1/8(默认即是 1/8)。
例如:

-XX:NewSize=64m -XX:MaxNewSize=1024m -XX:NewRatio=8

老年代(Old generation)

对象没有变得不可达,并且从新生代中存活下来,会被拷贝到这里。其所占用的空间要比新生代多。也正由于其相对较大的空间,发生在老年代上的GC要比新生代要少得多。对象从老年代中消失的过程,可以称之为major GC(或者full GC)。

永久代(permanent generation)

像一些类的层级信息,方法数据 和方法信息(如字节码,栈 和 变量大小),运行时常量池(JDK7之后移出永久代),已确定的符号引用和虚方法表等等。它们几乎都是静态的并且很少被卸载和回收,在JDK8之前的HotSpot虚拟机中,类的这些"永久的" 数据存放在一个叫做永久代的区域。
永久代一段连续的内存空间,我们在JVM启动之前可以通过设置-XX:MaxPermSize的值来控制永久代的大小。但是JDK8之后取消了永久代,这些元数据被移到了一个与堆不相连的称为元空间 (Metaspace) 的本地内存区域。

小结

JDK8堆内存一般是划分为年轻代老年代不同年代 根据自身特性采用不同的垃圾收集算法
对于新生代,每次GC时都有大量的对象死亡,只有少量对象存活。考虑到复制成本低,适合采用复制算法。因此有了From SurvivorTo Survivor区域。
对于老年代,因为对象存活率****高,没有额外的内存空间对它进行担保。因而适合采用标记-清理算法标记-整理算法进行回收。

总结

目前对比了.Net平台垃圾回收和jvm垃圾回收,对于垃圾回收算法和分代的概念,两者设计思路都相同,唯一的区别我个人觉的JDK8以后jvm的垃圾回收效率更高,根据不同的代使用不同的垃圾收集算法,这一点似乎是.Net平台垃圾回收没有实现的地方。

参考链接

https://www.geeksforgeeks.org/garbage-collection-in-c-sharp-dot-net-framework/
https://juejin.im/post/5b4dea755188251ac1098e98
https://kb.cnblogs.com/page/106720/
https://www.zhihu.com/question/31806845







Asp.Net Core 3.1学习

Asp.Net Core 3.1学习


1、前言

面向对象设计(OOD)里有一个重要的思想就是依赖倒置原则(DIP),并由该原则牵引出依赖注入(DI)、控制反转(IOC)及其容器等概念。在学习Core依赖注入、服务生命周期之前,下面让我们先了解下依赖倒置原则(DIP)、依赖注入(DI)、控制反转(IOC)等概念,然后再深入学习Core依赖注入服务。

 

2、依赖倒置原则(Dependency Inversion  Principle, DIP

抽象不应该依赖于细节,细节应当依赖于抽象,高层模块不依赖于低层模块的实现,而低层模块依赖于高层模块定义的接口。一般来讲,就是高层模块定义接口,低层模块负责具体的实现。针对接口编程而不是针对细节编程

3、什么是依赖注入(Denpendency Injection)

3.1、依赖

人与人之间都有依赖(尤其我,就是离不开女人哈哈)何况软件呢?所谓依赖就是:当一个类需要另一个类协作来完成工作的时候就产生了依赖。比如用户登录,我们在控制器中UserController要完成用户登录、注册、修改密码等等事情、其中操作到数据库的(登录)我们用EF来完成,这里我们封装了一个EFLogin,这里的UserController就有一个ILogin的依赖。需要知道的是这里依赖于一个抽象为不是具体的某一个实现,所以给EFLogin定义了一个接口ILogin抽象了EFLogin的行为

3.2、注入

注入体现的是一个IOC(控制反转的的思想)。

 public interface IUser {  string BB(); } public class User : IUser {  public string BB()  {   return "LP整天只会BB";  } } public class ShowInfo {  IUser user = new User();  public void UserBB()  {   user.BB();  } }

当我们调用ShowInfo的时候,是通过IUser接口实例化一个User类去实现其方法的这叫控制正传, 但是大湿兄说,我们不应该创建User类,而是让调用者给你传递,于是你通过构造函数让外界把这两个依赖给你。把依赖的创建丢给其它人。自己只负责使用,其它人丢给你依赖的这个过程理解为注入其它人丢给你依赖的这个过程理解为注入。也叫控制反转(IOC)

public interface IUser {  string BB(); } public class User : IUser {  public string BB()  {   return "LP整天只会BB";  } }  public class ShowInfo2 {  private readonly IUser _user;  public ShowInfo2 (IUser user)  {   _user = user;  }  public void UserBB()  {   _user.BB();  } }

 3.3、为什么要使用依赖注入?

使用依赖注入我们可以很好的管理类跟类之间的依赖,在我们设计应用程序的时候遵循这几原则,确保代码的可维护性和扩展性;另外在Core的架构中依赖注入提供了对象创建和生命周期管理的核心能力,各个组件之间的相互协作也是由依赖注入框架来实现的

4、服务生命周期

在ConfigureServices方法中的容器注册每个应用程序的服务,Asp.Core都可以为每个应用程序提供三种服务生命周期:
Transient(暂时):每次请求都会创建一个新的实例。这种生命周期最适合轻量级,无状态服务。
Scoped(作用域):在同一个作用域内只初始化一个实例 ,可以理解为每一个请求只创建一个实例,同一个请求会在一个作用域内。在Scooped的生存周期内,如果容器释放 它也就被释放了
Singleton(单例):整个应用程序生命周期以内只创建一个实例,后续每个请求都使用相同的实例。如果应用程序需要单例行为,建议让服务容器管理服务的生命周期,而不是在自己的类中实现单例模式。

为了演示生命周期和注册选项之间的差异,请考虑以下代码:

 

 

IGuid接口返回一个Guid

public interface IGuid {  Guid GetGuid { get; } }

接口IScopedService、ISingletonService、ITransientService、都继承接口IGuid

 public interface IScopedService:IGuid {   } public interface ISingletonService: IGuid {   } public interface ITransientService: IGuid {   }
 GuidShow类继承接口IScopedService、ISingletonService、ITransientService
public class GuidShow : IScopedService, ISingletonService, ITransientService {    public GuidShow() : this(Guid.NewGuid())  {  }  public GuidShow(Guid id)  {   GetGuid = id;  }  public Guid GetGuid { get; private set; } }

 在Starup里面注册

public void ConfigureServices(IServiceCollection services)  {   #region//注册不同生命周期的服务   services.AddSingleton<ISingletonService, SingletonService>();   services.AddTransient<ITransientService, TransientService>();   services.AddScoped<IScopedService, ScopedService>();   

2020开年营销,看品牌如何借势3·8女神节

2020开年营销,看品牌如何借势3·8女神节


 短视频,自媒体,达人种草一站服务

文|烧脑广告(shukewenzhai)

由于疫情的影响,很多人在家憋得浑浑噩噩,也有很多品牌和商家受到经济打击。但随着春天的到来,以及疫情受到控制,各行各业逐渐复工,人们和经济像万物春生一样开始复苏。

品牌们也迎来了2020年真正的首次开年大促——即将到来的三月八日国际劳动妇女节。女性不断努力提升群体社会地位,证明自身的魅力和实力,使女性群体得到了更多的尊重和爱护。也让妇女节有了更多名字,如“女神节”、“女王节”、“女皇节”等。

女性作为市场的一大消费主力,在这一天,自然会有不少品牌推出妇女节广告和相应的营销活动,传递品牌对女性价值的认可,以促进和女性消费者的关系。

今年的38妇女节营销少了很多,但仍有优秀的作品值得看看。

Apple

在3.8来临之际,Apple 为我们介绍了许多优秀女性。

我们教导女孩小看自己

让她们自觉渺小

我们跟女孩说

你可以进取

但别太进取

你应该追求成功

但别太成功

不然别人会受到威胁

醒醒吧,我们生来完美无瑕

摆姿势,完美无瑕

走一圈,完美无瑕

炫一下,完美无瑕

我生来完美无瑕

女孩们告诉他们

我生来完美无瑕

......

这个广告延续了苹果在2018年推出的《致背后的你》系列主题,这系列广告采用黑白静态影像的方式展示那些Mac和用户的故事,借此向Mac背后的创造者致敬。这系列广告的第一期介绍了Mac背后各行各业的生活创造者,第二次介绍了各大院校的大学生创作者,而这次则将镜头聚焦在默默为改变世界而努力的那些优秀女性身上。

出镜的人物包括各行各业有影响力,为社会做出贡献,将自我价值体现得淋漓尽致的女性:

Malala Yousafzai:因“为受剥削的儿童及年轻人、为所有孩子的受教育的权利抗争”,与凯拉什·萨蒂亚尔希共同获得2014年诺贝尔和平奖。Ava Duvernay,:反对种族歧视和民权运动题材的传记电影《塞尔玛》和美剧《有色眼镜》导演。Marie Kondo:登上时代杂志中全球最具影响力100人榜单,整洁女王、畅销书作家、艾美奖提名电视明星。Gloria Steinem:女权活跃分子,帮助发起了第二波女权主义。Lady Gaga:格莱美和奥斯卡大奖获得者,Born This Way 基金会创始人。

伴随着BGM里碧昂斯的那首《Flawless》,那些黑白的照片却让人看出了多彩,这没有台词的广告却让人听到了更多的声音,感受到了更大的力量。

同时,苹果还在Apple Store举行“She Creates”活动,展现女性们在专属领域的风采。中国区 App Store 首页还更新三个女性力量专栏,带大家了解中国女性开发者心路历程。

并分享各种女性打造的应用、电视、图书和音乐等内容,例如,游戏区推出了编辑精选的“巾帼不必让须眉”主题,向玩家推荐以女性为主角或者主视角的优秀移动游戏。

Apple Music 上,首页也更新为女性喝彩的专题,展示了许多女声音乐、音乐中的女性主义、歌坛天后代表作以及国语流行乐坛几位实力女唱将的代表作。

Levi’s

似乎女孩来到这个世界,就被定义了,女孩就该有女孩的样子。可 Levi’s 却说,女孩的身份只是最初的形状,每个女孩都将有自己的形状。

我们以女孩的形状

来到这个世界

开始探寻自己的边界

当我们打破一些规矩

走出自己的步调

当我们不再害怕领先

敢于追逐自己的幸福

当我们把极限推得越来越远

我们勇敢跨出的每一步

都让我们有了自己的形状

穿上Levi’s 妳就型

这支广告以女孩的个性视角,基于当代中国女性在职场、家庭等方面的发展轨迹与情感诉求,讲述了6位先锋女性敢于打破定义、超越边界、追求极限的故事,激励更多女性勇敢表达自我。

麦子,身兼先锋导演、芭蕾舞者、话剧演员等多重身份。邱明,滑板、网球篮球爱好者、健身达人兼职模特。钟盛真,是平面模特更是摩托车全国冠军,她以狂野不羁的形象符号闯进了以男人为主导的骑士世界,连续两次摘得全国雪地摩托锦标赛冠军。

每个女孩都有不同的成长故事和人生经历,就像每一条牛仔裤都无法复制。Levi’s借此想法提出“裤随妳型”的主题,除了广告片以外,Levi’s 还在小程序推出“裤女孩”专属定制,并发起 #裤女孩型动# 话题互动,激发女性消费者对自我的思考。

面对质疑和挑战,选择按部就班还是走出自己的步调?这都由女孩自己决定。健康正确的状态不会束缚身体和灵魂,选择适合自己的生活方式,才能找到属于自己的形状。

作为一个极具个性的先锋品牌,Levi’s一直致力于鼓励与帮助女性由内而外的塑造自我。

1934年,Levi’s 开创了世界上第一条女士牛仔裤——Lady Levi’s 701。这款牛仔裤的设计之初是为工作的女孩提供结实的工作服,证明她们可以和男性一样有能力胜任。并在之后的发展中,Levi’s 不断努力为女性打造更舒适、时尚的牛仔裤。

Levi’s 全球设计团队曾走遍世界十多个国家,采集上万个女性体型样本,为不同风格的女性设计更适合自己的牛仔裤。这不仅带给女性在外型上的改变,更鼓励女性追求了身体上和精神上的突破与自由。

品牌的妇女节营销实际上是品牌对女性的理解,可以看出,如今讨好吹捧女性的广告已显得尤为空洞,而真正理解尊重,彰显女性的力量的广告更容易被接受认可。


亚马逊站外推广实操干货,教你如何站外引流【亚马逊运营必看】

亚马逊站外推广实操攻略,不多说,直接上干货。

一、社交推广

在国外,流行的社交平台有Facebook, Twitter, Pinterest , Quora, Instagram等,其中Facebook是零售渠道的王者。FB就像微博一样,需要建立你自己的专页,圈粉引流,那具体应该怎么做呢?

以下是facebook的推广步骤:

1. 建立facebook账户,增加目标国家的好友。比如做的是美国站,就加美国的好友。

2. 定期更新内容,保持账号活跃度。怎么打造内容?明确一个要做的垂直领域,运动、音乐、母婴、时尚都属于垂直领域,选择和产品相关的垂直领域做内容。明确领域后,要看一下领域内现在活跃的大V都是如何做的,然后找一个有差异化的点打造自己的账号。

3. 互动。和粉丝互动,认真回复粉丝的留言。组建和加入群组,群组是社交网站的核心,经常和群组的人互动,会给账号带来更多的流量。

4. 使用facebook里的商店插件,在商店里定期推出一些活动,给予你的粉丝一些好处。

5. 操作一段时间后,把账号养起来,就可以定期发布产品的广告文案引流了。

二、博客推广

利用wordpress、myspace、自己建立的博客等做产品推广,都属于博客推广。

以下是博客推广的思路:

1. 内容定位。注册博客平台,定位好要做的垂直领域,然后在博客中发布高质量的内容。

2. 关键词布局。将产品相关的热门搜索词统计出来,再植入到博客当中。

3. 做好内容和关键词的布局后,引入的流量就会精准许多,可以开始做产品的软文工作正式引流了。

三、邮件推广

邮件营销是非常好用的运营手段。做好邮件营销,需要握好发邮件的时间、标题、内容等等几个技巧,才能有效提高销量。

以下是邮件推广的步骤:

1. 利用独立站、社交媒体和粉丝群获取邮件地址

2. 打造邮件内容,安排好时间发送邮件。邮件的标题需要有吸引力,千万不要在标题中直接索评,这样会让买家十分反感。一天中的上午八点、下午一点和下午四点是平均打开率最高的时间段,而上午六点、上午八点和下午一点是平均点击率最高的时段(美国时间),所以建议在这几个时间点发送邮件。

四、图片推广

国外热门的图片网站有http://pinterest.com、http://fashiolista.com等。 这类网站的图片会有很多的标签,很多的长尾关键词来吸收流量。这类网站以图片为主,会给人更好的视觉冲击,能够刺激别人的购买欲望。

以下是Pinterest推广的步骤:

1. 注册Pinterest账户,设置好这些图片的标题及属性。

2. 添加自己店铺或者产品的链接。

3. 优化关键词,将图片的排名做上去,得到更多的流量。

五、YouTube红人推广

YouTube作为全球最大的视频社交平台,其全球活跃用户超过10亿人,它在各地的营销价值甚至远远超越某些市场本土的媒体,而且YouTube上更是有无数的网红可以用来做引流推广,利用好了能带来巨大的流量。

以下是YouTube红人推广的步骤:

1. 寻找红人。用第三方平台像contentblvd、brandbacker、influenster、IZEA、hyprbrands、Scrunch、Markrwatch、Famebit.com来寻找红人。

2. 筛选红人。用http://socialblade.com查询的红人名字,排名,视频数量,观看数量,订阅量,最近30天的订阅情况等等。

3. 合作谈判。准备好给红人写信的模板,用邮件联系。和红人沟通视频怎么做,不要忘了植入店铺的链接。

六、短视频营销

随着Tiktok的火爆,引起全体跨境卖家关注。因为Tiktok是新兴的,具有强大带货能力的平台,是难得的机遇,充满无限可能。

以下是Tiktok红人推广的步骤:

1. 产出垂直领域的视频内容。

2. 按照Tiktok算法指标的完播率、点赞率、评论率、转化率、关注比、复看率这六个要素去优化视频内容。

3. 植入跳入亚马逊店铺的链接,tiktok视频被分配到的流量越大,则引入店铺的流量就越多。

站外推广还有很多思路,像Deal网站促销、Review站引流、谷歌搜索广告等等,都是站外推广的有效方式。新手的话就多去实践,尽量多接触各种站外推广的营销策略。成熟的运营,优化当下的站外推广策略,并寻找新的推广途径即可做好站外推广。希望你看了这篇文章后能有所收获,让站外推广给你的店铺,有效的带来更多的流量。


文章来源:https://www.ikjzd.com/home/121013

2020年年广交会有多少人参加?2020年广交会外贸企业要做什么?

首先,面对疫情带来的全球经济洗牌,给企业带来机遇也带来挑战。大多企业的想法是:疫情全面结束之后占领处于"停滞"和"空白"的市场,这段时间是渗透和占领市场的最佳时机。

展会是可以带着自己的产品现场面对面的与潜在客户交流,演示产品、感受服务的最好方式。根据调查显示,利用展览会接触客户的平均成本仅为其他方式接触客户成本的10%。如果你想低成本接触客户,那么参加展览会是最有效的方式。

展会上的新产品是市场的强心剂,因为在全国因疫情导致全面停工的几个月中,市场亟需更多的新品和亮眼产品来引领,展会带来的新产品能迅速打开市场,将低迷的市场拉起来!

万众瞩目的第127届广交会,将于6月15-24日在网上举办。本届广交会如何举办,参展企业如何"云展示"及"云营销",都是大家关心的热点问题。

网上参展的企业范围

出口展:参展企业为已获第127届广交会展位安排的约2.5万家企业,展位数量和位置安排以大会公布为准。

进口展:参展企业为已完成第127届广交会展位费预付的境外展团和企业,预计有来自约30个国家和地区约4百家企业。

如何登录网上参展平台?

已获第127届广交会展位安排的约2.5万家出口展企业,以及约400家进口展企业,可使用原有参展易捷通系统的账号,登录参展平台,其他用户不可登录。

国内外采购商及观众,可通过广交会官网等入口,进入线上展览平台,进行登录注册、查询企业名称、浏览企业专属页面、点击产品信息、访问企业直播间等线上观展操作。

2020年广交会参展指引可点击下方链接查看,从资质到报名;参展到开发,你想知道的这里都有。

参展直播:线上广交会要直播?关于内容直播的推荐 一定要收藏好!

数量要求:每家企业在每个参展展区至少上传10个具有代表性的产品;获得1个以上展位的企业,每增加1个展位需增加上传5个产品;至少上传1个视频展示文件。上传展品数量不设上限;上传项目不少于下限要求。

信息质量:每件产品须提供详细的中英文名称、产品描述。图片、视频、3D展示文件等要清晰、特点突出。

结语  

随着市场的快速恢复,各行各业竞争也将更加激烈,加速行业洗牌,各行各业也将进入"强者更强"的境地。危机蕴藏着商机,而疫情过后便是行业快速恢复生产,市场展览营销的日子,如何在行业回暖之际快速抢占市场先机?这是关系到今年企业生死存亡的大问题,所有行业人士都寄于厚望。

部分摘自:中盈展


文章来源:https://www.ikjzd.com/home/121044

运营笔记:是时候了解蜘蛛爬取原理了!揭秘收录难题

运营笔记:是时候了解蜘蛛爬取原理了!揭秘收录难题


 短视频,自媒体,达人种草一站服务

很多人在做SEO的时候,搞不清蜘蛛爬取的原理或者对收录索引都搞不清关系,这篇文章主要针对实战来讲解蜘蛛和收录的关系,不讲原理,只讲干货和经验。

首先我们提到蜘蛛可能就可能想到IP,比如以下这些;

220.181.108.89专用抓取首页IP 权重段,一般返回代码是304 0 0代表未更新。

220.181.108.94专用抓取首页IP 权重段,一般返回代码是304 0 0代表未更新。

220.181.108.97专用抓取首页IP 权重段,一般返回代码是304 0 0代表未更新。

220.181.108.80专用抓取首页IP 权重段,一般返回代码是304 0 0代表未更新。

220.181.108.77 专用抓首页IP 权重段,一般返回代码是304 0 0代表未更新。

是不是很难理解?但是如果做过网络维护、或者局域网组网的就能明白,其实每个IP对应的就是一台电脑,每组服务器组对应的就是网段。

比如,220.181.108.x这个网段,我们暂且叫收录服务器组,这个服务器组下面有电脑ABCDE,对应的IP,每台电脑上装着相应的收录程序。

那么这样是不是清楚了呢?比如你提交一个链接到百度,那么相当于把这个链接提交到收录服务器组的C号电脑。

比如你提交了1、2、3个链接,这三个链接分别提交到了收录服务器组的C、D、E号电脑,所以你查看日志的时候会发现,这三条链接对应不同的IP,也就是对应着不同的电脑。

那为什么提交3条链接会提交到三台不同电脑呢?我个人猜测,或许提交的数据太多,同一台电脑处理不了,所以采取了分布处理方式。(个人猜测,并非是研究证明,或许是更高级的处理方式)。

我昨天针对这个做了一个测试,写了3篇原创文章,发布后,我以最短的时间查看蜘蛛爬取情况,结果这三篇文章,分别爬取的IP是;

116.179.32.135——服务器1

220.181.108.122——服务器2

220.181.108.180——服务器3

第一篇文章写完后,文章过几分钟秒收录,然后我模仿第一篇写作框架,继续写第二篇,第二篇也过几分钟秒收,然后接着写第三篇,可惜的是,第三篇没有收录。

但第二天,这三篇全部收录,也就是说,第三篇变成了隔天收录。

我又查看了116.179.32.135这个IP,这个IP属于山西省阳泉市 联通,目前很多人都奇怪现在出现了116.179.32.X网段的蜘蛛,现在可以确定 的是,这个网段就是百度蜘蛛,除了nslookup可以验证外,以下几点也是证据;

蜘蛛爬身上是报喜?是时候了解蜘蛛爬取原理了!揭秘收录难题!

另外百度李总裁老家也是阳泉的,所以几个证据足以说明,搜索服务器一部分也搬到了山西。

结合上面实战的经验包括以往收录爬取的蜘蛛分析,只要是链接提交到116.179.32.135,或者220.181.108.122、220.181.108.180等等,那么链接必定收录,所以唯一解开收录密码的难点在于,如果控制链接提交到这些服务器?

甚至有人戏谑称,220开头的是官方蜘蛛,而116开头是老家蜘蛛,呵呵,希望大佬一起来研究这个问题。

文章首发运营正经说:zhanzhang/779.html

申请创业报道,分享创业好点子。点击此处,共同探讨创业新机遇!


苏格兰网协希望穆雷兄弟参赛 穆雷:不必过快恢复比赛_网球

苏格兰网协希望穆雷兄弟参赛 穆雷:不必过快恢复比赛_网球


原标题:苏格兰网协希望穆雷兄弟参赛 穆雷:不必过快恢复比赛

北京时间4月29日,苏格兰网球协会表示希望安迪·穆雷和杰米·穆雷两兄弟能够参加在苏格兰举行的"闭门"赛事。

如今,网球赛事受到疫情影响停摆。据了解,杰米·穆雷正在与草坪网球协会就举办一场伦敦赛事进行深入谈判。对此,苏格兰网球协会主席布莱恩·多兹表示:"杰米正在英国做一些努力,我们正在苏格兰做一些努力。一旦我们有了更多的架构和资金,会联系杰米并询问他的想法。向他征求意见是我们的下一步计划。"

最近,安迪·穆雷正在参加马德里网球电竞赛。穆雷表示,"我认为尽快恢复网球赛事并非最重要的事,恢复正常生活才是当务之急。"返回搜狐,查看更多

责任编辑:


2020-04-29

岁月不饶人!国足名单已难寻85后球员身影,多人或就此告别国家队_冯潇霆

岁月不饶人!国足名单已难寻85后球员身影,多人或就此告别国家队_冯潇霆


原标题:岁月不饶人!国足名单已难寻85后球员身影,多人或就此告别国家队

李铁在公布新一期国足集训名单之后,细心的球迷可能会发现,名单中已经难寻85后球员的身影。结合李铁国足三次集训名单分析,多名85后老将都已经全面淡出国家队,取而代之的是以吴曦为首的89后球员,开始成为国家队核心力量。85后球员在国家队大赛中最后一次被集体重用,应该是2019年亚洲杯。

里皮带领国足出战2019年亚洲杯时,招入了肖智、郜林、赵旭日、冯潇霆等多名85后球员。值得一提的是这几位85后球员,在亚洲杯上基本上都得到了重用。郜林和冯潇霆是当时国足雷打不动的主力,赵旭日和肖智则是属于国足替补奇兵。

其中肖智在国足对阵泰国的16强淘汰赛上,替补登场上演了力挽狂澜的好戏,为球队打入了关键进球。国足这几位85后整体在亚洲杯上的表现不错,除了冯潇霆在对阵伊朗的亚洲杯八强战出现了一次防守托大,导致国家队城门失守。其余85后国脚都在比赛中发挥稳定,大有越踢越妖的趋势。

不过从现在的实际情况来分析,阿联酋亚洲杯已经成为国足85后球员的谢幕演出。里皮和李铁在执掌中国队帅印时,都没有再征召85后球员入队。那么未来85后球员,还有没有重返国家队的希望?这个问题的答案就要等到新赛季中超联赛开打,郜林、冯潇霆、肖智在比赛中表现如何才能揭晓。

从国足新老交替的长远目标来看,除非郜林和冯潇霆在新赛季中超有持续爆发的表现,否则85后球员已经很难再进国家队。球迷觉得国足在未来要是有机会出战十二强赛,球队主帅李铁可以考虑征召冯潇霆进队,前提是他在申花有定海神针的发挥。因为国足进入十二强赛之后,面临的都是亚洲一流强队,以国足目前的中卫配置很难抵御对手的狂轰滥炸。冯潇霆大赛经验丰富,而且踢中卫的水平在亚洲属于一流。

所以冯潇霆或许有希望在十二强赛时,被李铁征召到国家队。至于其他85后球员要想得到李铁重用,已经是不太现实的事情。尤其是像郜林和肖智这样的攻击型球员,他们未来重返国足得跟高水平归化竞争,这让两人入选国家队的希望就变得非常渺茫。希望以冯潇霆为首的85后老将,新赛季好好表现,再次迎来职业生涯巅峰。

(罗掌柜)返回搜狐,查看更多

责任编辑:


亚马逊日本站:洞察消费文化很重要!

最近几年爆火的亚马逊日本站吸引了许多卖家,经常耳闻有不间断的销量爆发,虽然消费单量相对美国站欧洲站稍低一些,操作空间也稍微低一点,但好的一面是,亚马逊日本站相对于其他站点更容易上手。今天数魔跨境给大家介绍一些亚马逊日本站选品的思路与启发。

一. 日本消费群体分析:

日本,是全球最大的电子商务市场之一,仅次于中国、英国、美国,线上购物的比重超过百分之80,除了本土购物平台,消费最高的就是亚马逊平台。尽管日本的线下超市购物非常方便,但是对于不那么追求品质或一定要线下试穿的消费者,更愿意在线上购买产品。有悟性的跨境人应该知道,日本的消费主体对为老年人。

有人会问,老年人还上网购物吗?回答是:那当然,日本老人可时尚了!今天的日本65岁以上已经超过3500万,65岁以上的比例已经超过27%,位居全球第一。那么在亚马逊日本站的买家年龄结构偏大,买家多数为老年人。

二.日本消费特点及热销产品:

日本是发达国家,消费水平深受西方影响,消费习惯也与欧美接近,除去日本特有的文化节日,大部分促销季也十分相似:圣诞、情人节、元旦,完全可以复制欧美站的重要节日礼品爆款,那么日本消费群体注重哪些文化呢?有什么是亚马逊日本站热销产品呢?

1)宠物文化

1176.png

日本的秋田犬是比较出名的,同时日本还有十几个猫岛,每个小岛上居住着数百只猫。日本人对于清洁和社会秩序是比较重视的,因此遛狗的人们都会随身带着塑料袋等物品,方便及时清理宠物的排泄物。所以装粪便的收纳器、宠物玩具、狗粮猫粮等周边产品都可能成为下一个爆款。

(2)送礼文化

互赠礼品在日本是极为普遍的现象,而这其中包含着独特的心理及文化因素。"程式化"是日本礼文化的一个显著特征,日本人送礼从内容到顺序基本上都是固定的,"礼尚往来"在日本人的送礼方式上得到了淋漓尽致的体现。各种节日、朋友见面、甚至搬家都要准备一些小礼物。小礼物的价值不会太高,但是频率很高,这里注意,梳子与手帕是日本人忌讳的谐音禁忌。综上所述,一些小的礼品如如首饰、别针、靠垫、创意居家小产品都是亚马逊日本站选品的热门。

(3)骑行文化

日本是世界上人口密度最高的国家之一,人多路窄,加上日本人不紧不慢的性格,形成了独特的自行车文化。日本的城市社区建设非常完善,骑车五到十分钟就能找到便利店、超市、学校等,解决日常所需,于是自行车成为了出门的理想工具。比起开车,日本人更愿意自行车配合电车的方式上班,让出行更有效率,更健康。骑自行车也成为了一种锻炼身体的城市风尚。因此,自行车以及自行车周边(车篮、车筐、车用水壶)都是非常不错的产品。

三、运营要点

日本消费者网购能力强,退货率较低,但是回评率也不是很高,建议对于日本站要索评哟。日本买家消费高峰时期:日本的公司普遍在12月发3~4个月的年终奖给员工,这就是日本买家资金最充裕的时间段也是亚马逊日本站卖家的销售旺季。对于日本站的店铺,要入乡随俗,把店铺名换为日文,因为日本消费者更喜欢本土产品,所以打造为本土化更受欢迎。

四、亚马逊日本站选品、索评工具

对于选品与索评建议亚马逊卖家可以借助一些站外工具。SellerMotor数魔跨境给亚马逊日本站的卖家推荐SellerMotor智能索评,一键索评高效率,方便快捷地提高回评率!对于选品SellerMotor数魔跨境推荐SellerMotor的浏览器插件,是一款亚马逊选品工具,提供类目选品、关键词选品、大数据选品,更能快速查询产品信息及上架销量,轻松助力日本站选品!

通过今天对亚马逊日本站的基本介绍,相信能给更多对亚马逊日本站选品有想法的跨境卖家提供一些新的思路。


来源:邦阅


文章来源:https://www.ikjzd.com/home/120949

Mercadolibre(美客多)平台开店入驻条件及流程最全详解,你想知道的都在这里!

sr lang="en" data-n-head="%7B%22lang%22:%7B%22ssr%22:%22en%22%7D%7D"> Mercadolibre(美客多)平台开店入驻条件及流程最全详解,你想知道的都在这里!-跨境知道

坐浴盆、理发器?宅在家的老外都在亚马逊上搜什么?

坐浴盆、理发器?宅在家的老外都在亚马逊上搜什么?


在浏览与新冠病毒相关的亚马逊搜索趋势时,不仅会联想起《丧尸生存指南》一书,该书讲解了人们如何在丧尸围城的世界中求生,人们应该储存那些必需品,例如食物、水、工具、汽油等等,同时还提醒人们必备一些游戏和休闲产品,以在世隔绝的状态下保持清醒。但这场病毒大灾难的主角是病毒以及其所带来的的民众恐慌心理和社交距离。可能有人会说,没有这么夸张吧,但数据不会说谎,在一月和四月之间:

• Puzzles for adults(成人拼图)的搜索量从每月13.8万攀升至每月100万以上

• Board games(棋类游戏)的搜索量从美元19.1万增长至每月40.8万

• Paint by numbers for adults(成人数字油画)的搜索量从每月13.8万增长至每月53.9万

除此之外,以下产品的搜索量也急剧攀升:

•Yeast/酵母

•Bidet/坐浴盆

•Hair clippers/理发器

•Weights/哑铃

•Elastic bands for sewing/缝纫松紧带

•Pulse oximeters/脉搏血氧仪

•Webcams/网络摄像头

"面点的诱惑"

自一月份以来,面粉的搜索量增长了近两倍,而酵母的搜索量惊人地增长了1200%。这样的趋势和国内极其相似,因疫情掀起一场面点烘焙热潮,酵母、面粉、黄油等产品陡然走俏。显而易见,烘焙已成为当下海内外非常流行的居家娱乐活动,而疫情之后面粉、酵母等产品的销售增长会趋于平缓,但趋势仍在。

坐浴盆的真香定律

因疫情宣布紧急状态后,美国各大超市纷纷上演"厕纸抢购大战",更有甚者盗窃餐厅和公共厕所的纸巾。这样的"厕纸慌"席卷美国后,一些美国人难逃被坐浴盆支配的恐惧。传统上,坐浴盆是放置在普通马桶旁边用来如厕后清洗的卫浴产品,许多人将坐浴盆视为厕纸的卫生替代产品,这在印度、日本等地很常见。但美国人历来不接受坐浴盆。

由于卫生纸的短缺,人们对坐浴盆等卫生设备的需求突然变得高涨。自1月以来,bidet(坐浴盆)的搜索量增加了400%(每月35.1万次搜索)。

自我护理

自线下理发店关门以来,hair clippers(剪发器)在亚马逊的搜索量增加了750%(达到每月67万)。同样伴随着健身房的关门,人们开始居家健身,购买各类运动器材。亚马逊上"哑铃"的搜索量从12月的15.1万增加了每月46.9万,而对阻力带的搜索量从12月的15.7万增长至63.9万(这里与12月相比,因为1月是运动器材的销售高峰)。

居家办公成常态

无论是在亚马逊,还是整个互联网上,搜索量激增的主要是work shirt(工作衫)而非work pants(工作裤)。因为大部分人在进行视频会议时,只是穿着正式的上衣上镜,而下身通常都穿着睡裤甚至内裤。

此外,自1月至今,每月居家办公设备的搜索量都在快速增长:

• Desk(办公桌)从27.9万上升至44.5万,增加了159%

• Office chair(办公椅)从31.2万上升至41.4万,增加了132%

• Webcam(网络摄像头)从7.3万上升至39万,增加了534%

医疗方面

众所周知,全球医用外科口罩非常短缺,越来越多的地方政府建议人们在公共场合戴布口罩,但由于"一罩难求",人们在这方面似乎变得越来越有创意,开始足智多谋,自己动手。

用于口罩制作的elastic bands for sewing(缝纫松紧带)的搜索量增长惊人:从1月的1.4万次搜索增加至本月的73.5万次,增长了5250%!。

随着越来越多的人在公共场合戴手套,disposable gloves(一次性手套)的搜索量自1月份以来增长了655%。

此外,由于COVID-19是一种呼吸道疾病,对于可能出现症状的人来说,可测量血液氧气含量的脉搏血氧计成为居家检查的一种选择。pulse oximeter(脉搏血氧计)的搜索量从每月9.7万次增加到每月62.6万次,增幅为645%。

(来源:小辣超有料)


网球——奥地利选手蒂姆进行训练_新华社

网球——奥地利选手蒂姆进行训练_新华社


原标题:网球——奥地利选手蒂姆进行训练

新华社照片,外代,2020年4月29日

4月28日,奥地利网球选手蒂姆在维也纳进行训练。

奥地利专业运动员从4月20日起被允许恢复训练,但需要采取严格的防疫措施。

新华社/欧新

返回搜狐,查看更多

责任编辑:


疫情给斋月期间的消费者行为带来哪些转变?

疫情给斋月期间的消费者行为带来哪些转变?


伊斯兰教是东南亚地区信奉人数最多的宗教,全球有16亿穆斯林,其中有2.4亿多穆斯林居住在马来西亚和印度尼西亚等国家。而斋月是伊斯兰教历中最神圣的月份,将于4月24日开始,5月23日结束。

在斋月期间,应用程序和网站上的在线行为,以及对不同产品、服务和内容的需求都会发生变化。了解这些变化如何以及何时影响你的目标受众的消费倾向,是使你与他们的购物意图保持一致,获得最佳广告回报的关键。

今年的斋月怎么过,也将受到COVID-19的影响,斋月时期附近的一些趋势会减弱,一些趋势会加强。

要注意到疫情带来的影响

目前疫情的肆虐会增加某些网站和页面的用户流量,而其他网站和页面的流量则会减少。社交距离措施和要求人们居家的呼吁增加,将改变人们的浏览习惯,很可能会使更多人使用网络,并改变他们浏览目的地。

例如,游戏行业观看直播的用户数量激增,而随着消费者点餐的增多,对食品外卖的需求也在增加,这很可能会进一步提高斋月期间及其相邻的几个月本已很高的APP下载量。

随着消费者通过应用和数字活动来庆祝斋月习俗,生活方式的内容甚至可能会超越往年的水平。随着虚拟环境取代了开斋节的实体聚会,社交和通信应用也可能会出现激增。

与此形成鲜明对比的是,由于全国范围内的旅行禁令、封锁以及消费者当中普遍存在的不确定性,可以预期旅行相关产品和内容的需求将急剧下降。在2018年和2019年数据中观察到的旅游APP下载量增长35%的情况,在2020年似乎不太可能出现。

通常情况下,电商网站的流量和电商APP的下载量激增,是由于信众为开斋节庆祝活动购买新衣服和礼物。由于今年许多集会受到限制,加上对消费者支出的潜在经济影响,电商活动很可能不会因为斋月而有任何收益。

然而,无论如何,电商活动在这一时期可能会有所增长,但任何增长都是受疫情影响的结果,如关闭实体零售店、社区封锁等。

广告商需要为斋月准备什么?

为了获得最佳的营销效果,品牌需要了解斋月如何影响目标市场,以及市场在这段时间内与产品类别的互动方式。

有一个仅仅针对斋月的广告计划是不够的,随着斋月临近,消费者的消费习惯现在就在改变。为了使你的广告效果最大化,你需要根据斋月期间你的产品类别的需求波动来安排。

研究受众的浏览习惯。了解行为的变化如何影响你的目标受众,这样你就可以在这段时间内根据他们的需求调整你的信息传递,并确保你在正确的渠道,在正确的时间触达他们。

把眼光放得更远一些。斋月的影响从斋月前的几周一直持续到斋月结束后的几周。在斋月前后的几周内,媒体成本和竞争也可能都会降低。根据你的类别,很可能有一个理想的时间来接触你的受众。

企业需要熟悉他们的受众何时开始研究过程,以及预计这些受众何时开始消费产品或服务。

保护你的预算不受广告欺诈。斋月为许多品牌提供了机会,当消费者对特定产品和服务的消费欲望高涨时,就可以让他们参与进来。利用这一点,意味着在短时间内获得更好的广告投资回报率。通过保护你的预算免受广告欺诈,来充分利用这个机会。

先知穆罕默德曾经告诉他的信徒,千万不要进入或离开有瘟疫的城镇,以免传播疾病。

对于今年的斋月来说,这个忠告似乎很及时。一年一度的伊斯兰教斋月已经来临,在这期间,穆斯林从日出到日落期间要禁食、禁酒。

由于采取了防止冠状病毒传播的社会隔离措施,大多数人这个月都不会离开家,更不用说离开城镇了。

很多人感到焦虑,但这个斋月还有人的处境要艰难得多。特别是一线的医护人员,他们要在没有足够的物资供应的情况下,长时间地投入到工作中,他们将在努力挽救生命的同时,独自禁食。

没有社区的斋饭,没有开斋饭。当地的清真寺都关门了。

社区的参与和礼拜

这一次,日常生活被打乱了,人们将面对的是另一种混乱。在封锁和隔离期间,怎么可能有对于斋月和禁食同样重要的社区参与和礼拜?

在正常的斋月里,人们每天晚上在别人家或清真寺里,都会吃上一顿美味的散伙饭。这种聚会对于没有家庭的人和没有收入的人来说尤其重要,不幸的是,现在这种情况很普遍。

杜勒斯地区穆斯林协会中心是弗吉尼亚州的一个大型清真寺,该清真寺的伊玛目Mohammad Magid表示,通常情况下,他预计在斋月期间,每晚会有600人到场参加集体祈祷。

而今年,他将在每天晚上在Zoom开展祈祷,由一组轮流背诵古兰经的人轮流主持,让每个人都能在家里听。一名社工将组织和协调为弱势成员送去食品杂货。

难以适应

适应起来很有挑战性。但他表示,每当他想抱怨的时候,他就会想到他在孟加拉国难民营里探访过的罗兴亚穆斯林。他说,即使在最恶劣的条件下,他们也毫无怨言地禁食。

对信仰和上帝的承诺

Saquib Rahim,一位在皇后区Flushing工作的内科医生,从疫情爆发的第一天起就开始治疗患者,他计划在今年禁食。

他暂时与家人分开居住,以避免遭受感染后传播病毒,他承认缺乏社区会非常困难。

(来源:跨境田鸡哥)


WishPost智选项目概览及常见问题解答(适用于项目所支持的所有路向目的国)

WishPost智选项目概览及常见问题解答(适用于项目所支持的所有路向目的国)


WishPost智选项目概览及常见问题解答(适用于项目所支持的所有路向目的国)

受海外新型冠状病毒疫情进一步扩散及航空公司大范围停航影响,国际航空运能大幅削减。鉴于此项局限,为帮助商户们应对一系列的相关物流挑战,例如多个物流渠道关闭、限量、或价格调整频繁,以及部分物流渠道无法保证成功交运订单,Wish现即将上线一项全新的物流方案供商户们考虑选择,名为"WishPost智选项目"。

请注意,WishPost智选项目目前支持通过WishPost直发的德国、比利时、和美国路向订单(因此,EPC,EPC Blue,和A+物流计划订单并不可参与到WishPost智选项目中),并将逐步扩展到更多的路向目的国。所涉及的订单将将受到"商户服务条款和协议"和"商户政策"约束。

同时也请注意,WishPost智选项目并不要求商户们参与,而是作为疫情期间可供商户们考虑加入的一个可选项目。

这篇文章为商户们提供WishPost智选项目的更多详情。

1. WishPost智选项目包含哪些物流渠道?

北京时间2020年4月23日早11:00时起,商户可使用下列WishPost物流渠道之一来履行德国和比利时路向的直发订单:

Wish邮智选经济 - 普货(otype: 5051-0)

Wish邮智选经济 - 特货(otype: 5052-0)

请注意,对于2020年4月29日下午3:00时上线的WishPost智选项目美国路向订单,商户可使用Wish邮智选经济 - 普货Wish邮智选标准 - 普货渠道来分别配送其普通产品(普货)的平邮和挂号的美国路向直发订单。我们在开始支持美国路向特货订单的时候,会及时通知商户们

对于德国和比利时路向的订单,商户需使用Wish邮智选经济 - 普货渠道来配送其普通产品(普货)订单(即非带电产品和非具有安全性问题的产品,如液体,粉末,膏状等均不属于普货),并使用Wish邮智选经济 - 特货渠道来配送其特殊产品(特货)订单。请商户们参考下述第8点,以了解WishPost智选项目所支持的具体特殊产品品类。

商户需准确申报包裹属性,并选择匹配的物流渠道进行配送。如果实物属性同所选择的物流渠道不一致,可能会导致包裹退回至商户。

若需将包裹属性通过ERP进行传输,各ERP应准备好接入以下新的API字段(请注意,以下新字段也适用于所有WishPost订单):

product_item_sensitivity_type

请商户们与自己的ERP合作方确认是否接入了该相关API字段。

下列API端口将受到影响:

/api/v2/create_order

2. 上述Wish邮智选渠道路向国的运费是多少?

由于每个路向国的运费结构均不一样,请分别访问以下文章,了解您所感兴趣的WishPost智选项目路向目的国的具体运费:

德国价卡:

WishPost智选项目概览及常见问题解答(适用于项目所支持的所有路向目的国)

比利时价卡:

WishPost智选项目概览及常见问题解答(适用于项目所支持的所有路向目的国)

美国价卡:

WishPost智选项目概览及常见问题解答(适用于项目所支持的所有路向目的国)

3. 上述Wish邮智选物流渠道都支持哪些揽收服务商?如何联系相关服务商?

以下表格展示了WishPost智选项目支持的三家揽收服务商的具体信息:

WishPost智选项目概览及常见问题解答(适用于项目所支持的所有路向目的国)

4. 我如果通过ERP选择以上Wish认可的揽收物流服务商,应该如何操作?

商户在通过ERP选择Wish认可的揽收物流服务商时,商户可调用WishPost的/api/v2/create_order接口创建WishPost智选项目订单。在使用该API接口时,商户需通过pickup_service参数选择揽收物流服务商。关于pickup_service参数,请注意:

1). 如doorpickup参数选择1(即上门揽收),则商户于pickup_service参数中必填27-1(万色揽收)或者42-0(燕文揽收)或者47-0(顺友揽收);

2). 如doorpickup参数选择0(即自配送),则可不填pickup_service参数;

3). 若未准确填写pickup_service参数,将导致物流订单创建失败,需要商户按照正确格式重新提交物流订单创建请求。

5. 我应该配送WishPost智选项目订单至哪个仓库地址?

商户可能需要将相关订单配送至以下仓库地点之一:

WishPost智选项目概览及常见问题解答(适用于项目所支持的所有路向目的国)

每一个订单相对应的仓库地址也会在WishPost账户中被指明为WishPost智选项目订单配送地址。

6. 配送至WishPost智选项目仓库的包裹有哪些尺寸和重量的限制?

最大重量 = 2kg;

尺寸限制:

1)方形货物最大及最小尺寸限制:长+宽+高 ≤ 90cm,单边长度 ≤ 60cm;表面尺码 ≥ 15cm × 10cm;

2)卷轴状货物最大及最小尺寸限制:17cm ≤ (直径的两倍 + 长度) ≤ 104cm,10cm ≤ 单边长度≤ 90cm;

3)只接收泡比 ≤ 1.5的货物,泡比 > 1.5倍的包裹将退回至商户;泡比 ≤ 1.5倍的包裹不记泡(即运费按照实重计算,而非泡重)。请注意(长 x 宽 x 高)÷ 6000 = 泡重,泡比 = 泡重/实重。

7. WishPost智选项目支持的最大申报价值是多少?

目前,WishPost智选项目并不接受申报价值超过22欧元的德国或比利时路向的包裹。同时,WishPost智选项目并不接受申报价值超过800美元的美国路向包裹。

8. 需要在WishPost上对特殊产品进行申报吗?

是的,商户必须在WishPost中正确地识别并申报特殊产品(带电类产品)。以下为WishPost智选项目目前可支持的特货品类:

WishPost智选项目概览及常见问题解答(适用于项目所支持的所有路向目的国)

请注意,WishPost智选项目目前仅支持普通产品和以上列出的特殊产品品类,其他所有品类均不支持。

9.WishPost智选项目和HUB中转仓项目的关系是什么?

商户可考虑利用HUB中转仓项目作为其WishPost智选项目订单首公里物流方案,以降低首公里物流成本并提高物流效率。请参考这份常见问题解答文章,以了解HUB中转仓项目能够如何帮助配送WishPost智选项目订单的商户们。

如以上信息没有解答您的问题,  您可联系WishPost客服, 我们将尽快给您答复。(来源:wish)
以上内容属作者个人观点,不代表立场!如有侵权,请联系我们。