日期: 2021 年 8 月 27 日

Android 中状态栏、标题栏、View的大小及区分

Android 中状态栏、标题栏、View的大小及区分

1、获得状态栏的高度(状态栏相对Window的位置):

Rect frame = new Rect();

getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);

int statusBarHeight = frame.top;

2、获得mView中显示内容的Top (不包括标题栏,指的是相对Window的位置,即:没有标题栏的时候,指的是状态栏的bottom在Window中的坐标;有标题栏的时候指的是标题栏的bottom在Window中的坐标)

getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();

3、获得view中显示内容,与window无关,只和父控件有关

如果布局文件中mView match_parent 那么top=0,bottom=mView.getHeight();

4、获得屏幕的宽高:

(1)

getResources().getDisplayMetrics().heightPixels;

getResources().getDisplayMetrics().widthPixels;

(2)

WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
int width = wm.getDefaultDisplay().getWidth();//屏幕宽度

int height = wm.getDefaultDisplay().getHeight();//屏幕高度

(3)

DisplayMetrics mDisplayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);
int W = mDisplayMetrics.widthPixels;
int H = mDisplayMetrics.heightPixels;

(4)过时方法

Display mDisplay = getWindowManager().getDefaultDisplay();
int W = mDisplay.getWidth();
int H = mDisplay.getHeight();

Rxlifecycle(三):坑

Rxlifecycle(三):坑

由于rx是从下到上的执行onsubscribe()方法,然后再自上到下的执行subscribe()方法,而rxlifecycle是使用takeUntil方法来停止消息,只能终止当前的上一个onsubscribe()方法的调用,所以顺便不同会出现以下问题

坑1

复制代码
复制代码
    Observable.just("hello world!")
            .compose(this.<String>bindUntilEvent(ActivityEvent.PAUSE))
            .flatMap(new Func1<String, Observable<Long>>() {
                @Override
                public Observable<Long> call(String s) {
                    return Observable.interval(1, TimeUnit.SECONDS);
                }
            })

            .subscribe(new Action1<Long>() {
                @Override
                public void call(Long aLong) {
                    Log.i(TAG, "....oh,oh,no!!..........." + aLong);
                }
            });
复制代码
复制代码

 

activity生命周期paused的时候

Log.i(TAG, "....oh,oh,no!!..........." + aLong);

还会执行么??会会…

如果你想全部都不执行:

复制代码
复制代码
Observable.just("hello world!")
            .flatMap(new Func1<String, Observable<Long>>() {
                @Override
                public Observable<Long> call(String s) {
                    return Observable.interval(1, TimeUnit.SECONDS);
                }
            })
            //fuck....here
            .compose(this.<Long>bindUntilEvent(ActivityEvent.PAUSE))
            .subscribe(new Action1<Long>() {
                @Override
                public void call(Long aLong) {
                    Log.i(TAG, "....oh,oh,no!!..........." + aLong);
                }
            });
复制代码
复制代码

坑2

复制代码
复制代码
    Observable.interval(1, TimeUnit.SECONDS)
            .doOnUnsubscribe(new Action0() {
                @Override
                public void call() {
                    Log.i(TAG, "Unsubscribing subscription ......");
                }
            })
            .doOnNext(new Action1<Long>() {
                @Override
                public void call(Long aLong) {
                    Log.i(TAG, "........fuck..........." + aLong);
                }
            })
            .flatMap(new Func1<Long, Observable<String>>() {
                @Override
                public Observable<String> call(Long aLong) {
                    return Observable.just(aLong + "");
                }
            })
            .compose(this.<String>bindUntilEvent(ActivityEvent.PAUSE))
            .subscribe(new Action1<String>() {
                @Override
                public void call(String num) {
                    Log.i(TAG, "..........shit..........." + num);
                }
            });
复制代码
复制代码

 

activity在paused的时候,

Log.i(TAG, "........fuck..........." + aLong);
Log.i(TAG, "..........shit..........." + num);

都不会执行…

而且会unsubscribe

Rxlifecycle(二):源码解析

Rxlifecycle(二):源码解析

1.结构

Rxlifecycle代码很少,也很好理解,来看核心类。

  • 接口ActivityLifecycleProvider

    RxFragmentActivity、RxAppCompatActivity、RxFragment等类所有的组件类皆实现这个借口

  • 类RxLifecycle

2.详细分析

以RxAppCompatActivity入手来分析。

  1. 初始化一个BehaviorSubject,Subject因为它是一个Observer,它可以订阅一个或多个Observable;又因为它是一个Observable,它可以转发它收到(Observe)的数据,也可以发射新的数据。Subject的详细介绍:https://mcxiaoke.gitbooks.io/rxdocs/content/Subject.html
    private final BehaviorSubject<ActivityEvent> 
        lifecycleSubject = BehaviorSubject.create();
  2. 在activity每个生命的周期Subject发射相对应的事件。
    复制代码
    复制代码
    @Override
    @CallSuper
    protected void onStart() {
        super.onStart();
        //发送start事件
        lifecycleSubject.onNext(ActivityEvent.START);
    }
    ....
    复制代码
    复制代码

分析RxLifecycle核心的方法:bindUntilActivityEvent

  1. bindUntilActivityEvent也就是调用的bindUntilEvent
    复制代码
    复制代码
    private static <T, R> Observable.Transformer<T, T> bindUntilEvent(final Observable<R> lifecycle,        
    //返回 Transformer                                  final R event) {
    return new Observable.Transformer<T, T>() {
        @Override
        public Observable<T> call(Observable<T> source) {
            return source.takeUntil(
                lifecycle.takeFirst(new Func1<R, Boolean>() {
                    @Override
                    public Boolean call(R lifecycleEvent) {
                        return lifecycleEvent == event;
                    }
                })
            );
        }
    };
    }
    复制代码
    复制代码

     

这个方法接收两个参数,lifecycle就是activity里面的BehaviorSubject对象,event就是要我们设置的要在activity哪个生命周期取消订阅的ActivityEvent对象。

返回参数是Transformer,用来结合compose使用 Transformer相当于一个过滤器,Observable call(Observable source) 接收一个Observable然后经过处理再返回一个Observable

这个方法从里到外一层一层剥开:

复制代码
复制代码
lifecycle.takeFirst(new Func1<R, Boolean>() {
                    @Override
                    public Boolean call(R lifecycleEvent) {
                        return lifecycleEvent == event;
                    }
                })
复制代码
复制代码

如果lifecycleEvent == event结果为true,lifecycle既BehaviorSubject对象发射一个数据。

lifecycleEvent是BehaviorSubject发射的数据,既ActivityEvent对象,比如在onStart时候lifecycleSubject.onNext(ActivityEvent.START)发送的ActivityEvent.START。 event是传递进来的参数。

接着上看

return source.takeUntil()

lifecycle*核心的就是这个takeUntil。

source就是要调用compose的原始的Observable,就是例子中这个Observable

  Observable.interval(1, TimeUnit.SECONDS)
      .compose(this.<Long>bindUntilEvent(ActivityEvent.PAUSE))
      ...

来看takeUntil:

Returns an Observable that emits the items emitted by the source Observable until a second Observable emits an item.

如果lifecycle.takeFirst发射了一条数据,takeUntil就回触发,source Observable就回停止发射数据,执行Unsubscribe,流自动结束。

分析RxLifecycle核心的方法:bindUntilActivityEvent

上代码

复制代码
复制代码
private static <T, R> Observable.Transformer<T, T> bind(Observable<R> lifecycle,
                                                        final Func1<R, R> correspondingEvents) {
        ...
    // Make sure we're truly comparing a single stream to itself
    final Observable<R> sharedLifecycle = lifecycle.share();

    // Keep emitting from source until the corresponding event occurs in the lifecycle
    return new Observable.Transformer<T, T>() {
        @Override
        public Observable<T> call(Observable<T> source) {
            return source.takeUntil(
                Observable.combineLatest(
                    sharedLifecycle.take(1).map(correspondingEvents),
                    sharedLifecycle.skip(1),
                    new Func2<R, R, Boolean>() {
                        @Override
                        public Boolean call(R bindUntilEvent, R lifecycleEvent) {
                            return lifecycleEvent == bindUntilEvent;
                        }
                    })
                    .onErrorReturn(RESUME_FUNCTION)
                    .takeFirst(SHOULD_COMPLETE)
            );
        }
    };
}
复制代码
复制代码
  1. .share()操作符:
  2. 来看Observable.combineLatest,这个操作符接收三个参数。

    *个参数:取BehaviorSubject发射的数据中的*个,然后转换成对应的生命周期。例如在onStart()中调用了bindToLifecycle,take(1)后的数据是ActivityEvent.START,经过map(),返回ActivityEvent.STOP。

    第二个参数:从BehaviorSubject发射的数据中经过.skip(1)操作符,过滤掉*个数据。例如在onStart()中调用了bindToLifecycle,在后续的生命周期中会收到,ActivityEvent.RESUME、ActivityEvent.PAUSE、ActivityEvent.STOP、ActivityEvent.DESTROY

    第三个参数:作用是combineFunction,把前两个参数*近发射的数据按照规则进行合并。规则是比对两次事件是否相等,然后合并后数据返回Boolean结果。比如params2发射ActivityEvent.RESUME的时候,和params1发射的ActivityEvent.STOP进行比对,返回false结果;params2发射ActivityEvent.STOP的时候,和params1发射的ActivityEvent.STOP进行比对,返回true结果。

  3. onErrorReturn()
    复制代码
    复制代码
    private static final Func1<Throwable, Boolean> RESUME_FUNCTION = new Func1<Throwable, Boolean>() {
    @Override
    public Boolean call(Throwable throwable) {
        if (throwable instanceof OutsideLifecycleException) {
            return true;
        }
    
        Exceptions.propagate(throwable);
        return false;
    }
    };
    复制代码
    复制代码

    如果发生错误,判断是否是自定义错误类型 OutsideLifecycleException,如果是,则返回true,否则其他错误类型返回false。

  4. .takeFirst(SHOULD_COMPLETE)
    复制代码
    复制代码
    private static final Func1<Boolean, Boolean> SHOULD_COMPLETE = new Func1<Boolean, Boolean>() {
        @Override
        public Boolean call(Boolean shouldComplete) {
            return shouldComplete;
        }
    };
    复制代码
    复制代码

    返回*个结果是true的数据。如果combineLatest链中返回false,则不发射任何数据。

  5. source.takeUntil

    如果combineLatest.onErrorReturn.takeFirst链返回true,则takeUntil操作符终止订阅,source Observable就回停止发射数据,执行Unsubscribe,流自动结束。

OVER!

RxJava操作符之Share, Publish, Refcount

RxJava操作符之Share, Publish, Refcount

看源码知道.share()操作符是.publish().refcount()调用链的包装。

先来看ConnectedObservable

“ConnectedObservable” – This is a kind of observable which doesn’t emit items even if subscribed to.
It only starts emitting items after its .connect() method is called.

因为这个原因,在ConnectedObservable的connect这个方法被调用之前,connected obesrvable也被认为是“冷”和不活跃。

再看publish方法

.publish()– This method allows us to change an ordinary observable into a “ConnectedObservable”.
Simply call this method on an ordinary observable and it becomes a connected one.

现在我们知道了share操作符的1/2,那么为什么需要运用Connected Observable这个操作符呢?文档上是这么写的:

In this way you can wait for all intended Subscribers to subscribe to the Observable before the Observable begins emitting items.

这就意味着publish可以调用多个subscriber。当你有超过一个订阅者的时候,处理每个订阅和正确的销毁他们变得棘手。 为了使这个更方便,Rx发明了这个魔法操作符refcount():

refcount() – This operator keeps track of how many subscribers are subscribed to the resulting Observable and
refrains from disconnecting from the source ConnectedObservable until all such Observables are unsubscribed.

refcount本质上在后台维护着一个引用计数器,当一个subscription需要取消订阅或者销毁的时候,发出一个正确的动作。

我们再次看一下debouncedBuffer的例子,看一下在哪,share是怎么用的。

Observable<Object> tapEventEmitter = _rxBus.toObserverable().share();
// which is really the same as:
Observable<Object> tapEventEmitter = _rxBus.toObserverable().publish().refcount();

我们现在有了一个”shareable”的名字叫”tapEventEmitter”的observable。 因为他是可以分享的,而且还不是“live”(share操作符中的publish调用使其变成一个ConnectedObservable), 我们可以用他构成我们的Observables,而且要确保我们有了一个原始的observable的引用 (这个例子中原始的observable是_rxBus.toObserverable()).

Observable<Object> tapEventEmitter = _rxBus.toObserverable().share();
Observable<Object> debouncedEventEmitter = tapEventEmitter.debounce(1, TimeUnit.SECONDS);
tapEventEmitter.buffer(debouncedEventEmitter)
//...

所有的这一切看起来都很好。然而这个实现会有一个可能的竞争条件。因为这有两个subscribers(debounce and buffer)而且会在不同的时间点发生,所以竞争条件就会发生。 记住RxBus是由hot/live Subject支持的不断的发射数据。通过使用share操作符,我们保证引用的是同一个资源。 而不是subscribers在不同的时间点订阅,他们会收到准确的相同的数据。

The race condition is when the two consumers subscribe. Often on a hot stream it doesn’t matter when subscribers come and go,and refCount is perfect for that.
The race condition refCount protects against is having only 1 active subscription upstream. However,if 2 Subscribers subscribe to a refcounted stream that emits 1, 2, 3, 4, 5, the first may get 1, 2, 3, 4, 5 and the second may get 2, 3, 4, 5.

To ensure all subscribers start at exactly the same time and get the exact same values, refCount can not be used.
Either ConnectableObservable with a manual, imperative invocation of connect needs to be done, or the variant of publish(function)which connects everything within the function before connecting the upstream.

在我们的用法中几乎立即执行所以没有什么关系。但是我们原始的意图是把debouncedBuffer方法作为一个单独的操作符。 如果相同的事件没有被发射出去,从概念上看起来是不正确的。

通过Bean后来的建议,我添加了一个更好的第三方的实现,用来处理这种竞争条件。

复制代码
复制代码
// don't start emitting items just yet by turning the observable to a connected one
ConnectableObservable<Object> tapEventEmitter = _rxBus.toObserverable().publish();

tapEventEmitter.publish((Func1) (stream) -> {

// inside `publish`, "stream" is truly multicasted

// applying the same technique for getting a debounced buffer sequence
    return stream.buffer(stream.debounce(1, TimeUnit.SECONDS));

}).subscribe((Action1) (taps) {
_showTapCount(taps.size());
});

// start listening to events now
tapEventEmitter.connect();
复制代码
复制代码

 

Rxlifecycle(一):使用

Rxlifecycle(一):使用

Rxlifecycle使用非常方便简单,如下:

1.集成

build.gradle添加

复制代码
复制代码
   //Rxlifecycle
   compile 'com.trello:rxlifecycle:0.3.1'
   compile 'com.trello:rxlifecycle-components:0.3.1'

   //Rxjava
   compile 'io.reactivex:rxjava:1.0.16'
复制代码
复制代码

 

Components包中包含RxActivity、RxFragment等等,可以用Rxlifecycle提供的,也可以自定义。

2.Sample解析

官方sample源码: 两种使用方法:

1.手动设置取消订阅的时机,例子1、例子3

2.绑定生命周期,自动取消订阅,例子2

复制代码
复制代码
public class MainActivity extends RxAppCompatActivity {

//Note:Activity需要继承RxAppCompatActivity,fragment需要继承RxFragment,等等
//可以使用的组件在components包下面

private static final String TAG = "RxLifecycle";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(TAG, "onCreate()");
    setContentView(R.layout.activity_main);

    // Specifically bind this until onPause()

    //Note:例子1:
    Observable.interval(1, TimeUnit.SECONDS)
            .doOnUnsubscribe(new Action0() {
                @Override
                public void call() {
                    Log.i(TAG, "Unsubscribing subscription from onCreate()");
                }
            })
            //Note:手动设置在activity onPause的时候取消订阅
            .compose(this.<Long>bindUntilEvent(ActivityEvent.PAUSE))
            .subscribe(new Action1<Long>() {
                @Override
                public void call(Long num) {
                    Log.i(TAG, "Started in onCreate(), running until onPause(): " + num);
                }
            });
}

@Override
protected void onStart() {
    super.onStart();
    Log.d(TAG, "onStart()");

    //Note:例子2:
    // Using automatic unsubscription, this should determine that the correct time to
    // unsubscribe is onStop (the opposite of onStart).
    Observable.interval(1, TimeUnit.SECONDS)
            .doOnUnsubscribe(new Action0() {
                @Override
                public void call() {
                    Log.i(TAG, "Unsubscribing subscription from onStart()");
                }
            })
            //Note:bindToLifecycle的自动取消订阅示例,因为是在onStart的时候调用,所以在onStop的时候自动取消订阅
            .compose(this.<Long>bindToLifecycle())
            .subscribe(new Action1<Long>() {
                @Override
                public void call(Long num) {
                    Log.i(TAG, "Started in onStart(), running until in onStop(): " + num);
                }
            });
}

@Override
protected void onResume() {
    super.onResume();
    Log.d(TAG, "onResume()");

    //Note:例子3:
    // `this.<Long>` is necessary if you're compiling on JDK7 or below.
    // If you're using JDK8+, then you can safely remove it.
    Observable.interval(1, TimeUnit.SECONDS)
            .doOnUnsubscribe(new Action0() {
                @Override
                public void call() {
                    Log.i(TAG, "Unsubscribing subscription from onResume()");
                }
            })
            //Note:手动设置在activity onDestroy的时候取消订阅
            .compose(this.<Long>bindUntilEvent(ActivityEvent.DESTROY))
            .subscribe(new Action1<Long>() {
                @Override
                public void call(Long num) {
                    Log.i(TAG, "Started in onResume(), running until in onDestroy(): " + num);
                }
            });
}
...
复制代码
复制代码

 

2021年1—7月份全国规模以上工业企业利润同比增长57.3% 两年平均增长20.2%

  1—7月份,全国规模以上工业企业实现利润总额49239.5亿元,同比增长57.3%(按可比口径计算,详见附注二),比2019年1—7月份增长44.6%,两年平均增长20.2%。   1—7月份,规模以上工业企业中,国有控股企业实现利润总额15837.1亿元,同比增长1.02倍;股份制企业实现利润总额34871.1亿元,增长62.4%;外商及港澳台商投资企业实现利润总额13330.5亿元,增长46.0%;私营企业实现利润总额14267.6亿元,增长40.2%。   1—7月份,采矿业实现利润总额4811.1亿元,同比增长1.45倍;制造业实现利润总额41374.7亿元,增长56.4%;电力、热力、燃气及水生产和供应业实现利润总额3053.7亿元,增长5.4%。   1—7月份,在41个工业大类行业中,36个行业利润总额同比增长,2个行业扭亏为盈,1个行业持平,2个行业下降。主要行业利润情况如下:石油和天然气开采业利润总额同比增长2.67倍,有色金属冶炼和压延加工业增长2.00倍,黑色金属冶炼和压延加工业增长1.82倍,化学原料和化学制品制造业增长1.62倍,煤炭开采和洗选业增长1.28倍,计算机、通信和其他电子设备制造业增长43.2%,电气机械和器材制造业增长30.2%,通用设备制造业增长25.7%,非金属矿物制品业增长21.0%,汽车制造业增长19.7%,专用设备制造业增长17.7%,纺织业增长4.2%,农副食品加工业增长0.7%,电力、热力生产和供应业下降2.8%,石油、煤炭及其他燃料加工业由同期亏损转为盈利。   1—7月份,规模以上工业企业实现营业收入69.48万亿元,同比增长25.6%;发生营业成本58.11万亿元,增长24.4%;营业收入利润率为7.09%,同比提高1.43个百分点。   7月末,规模以上工业企业资产总计133.41万亿元,同比增长9.0%;负债合计75.16万亿元,增长8.2%;所有者权益合计58.25万亿元,增长10.1%;资产负债率为56.3%,同比降低0.4个百分点。   7月末,规模以上工业企业应收账款17.84万亿元,同比增长13.3%;产成品存货5.08万亿元,增长13.0%。   1—7月份,规模以上工业企业每百元营业收入中的成本为83.63元,同比减少0.79元;每百元营业收入中的费用为8.41元,同比减少0.61元。   7月末,规模以上工业企业每百元资产实现的营业收入为91.5元,同比增加11.8元;人均营业收入为162.6万元,同比增加32.7万元;产成品存货周转天数为17.5天,同比减少2.1天;应收账款平均回收期为51.6天,同比减少4.8天。   7月份,规模以上工业企业实现利润总额7036.7亿元,同比增长16.4%。    表1  2021年1—7月份规模以上工业企业主要财务指标  分 组 营业收入 营业成本 利润总额 1-7月 同比增长 1-7月 同比增长 1-7月 同比增长 (亿元) (%) (亿元) (%) (亿元) (%) 总计 694769.5 25.6 581062.0 24.4 49239.5 57.3 其中:采矿业 27703.4 30.8 18616.4 17.9 4811.1 144.6    制造业 615335.8 26.0 516403.3 25.1 41374.7 56.4    电力、热力、燃气及水生产和供应业 51730.2 18.1 46042.2 20.0 3053.7 5.4 其中:国有控股企业 181597.6 25.6 146119.2 23.0 15837.1 102.2 其中:股份制企业 515377.3 27.0 431413.6 25.8 34871.1 62.4    外商及港澳台商投资企业 159396.5 21.6 132621.4 20.6 13330.5 46.0 其中:私营企业 271614.7 26.1 234326.0 25.6 14267.6 40.2 注: 1.经济类型分组之间存在交叉,故各经济类型企业数据之和大于总计。 2.本表部分指标存在总计不等于分项之和情况,是数据四舍五入所致,未作机械调整。  表2  2021年1—7月份规模以上工业企业经济效益指标  分 组 营业收入 利润率 每百元营业 收入中的成本 每百元营业 收入中的费用 每百元资产实现的营业收入 人均营业 收入 资产负债率 产成品存货周转天数 应收账款 平均回收期 1-7月 1-7月 1-7月 7月末 7月末 7月末 7月末 7月末 (%) (元) (元) (元) (万元/人) (%) (天) (天) 总计 7.09 83.63 8.41 91.5 162.6 56.3 17.5 51.6 其中:采矿业 17.37 67.20 11.04 45.2 112.9 59.4 12.8 39.8    制造业 6.72 83.92 8.48 107.9 160.6 55.4 19.2 52.3    电力、热力、燃气及水生产和供应业 5.90 89.00 6.17 40.5 264.1 59.3 0.9 48.8 其中:国有控股企业 8.72 80.46 7.21 63.4 250.7 57.0 12.7 41.2 其中:股份制企业 6.77 83.71 8.51 88.9 161.3 57.1 17.8 48.9    外商及港澳台商投资企业 8.36 83.20 8.43 101.7 167.1 53.4 17.8 63.0 其中:私营企业 5.25 86.27 8.37 127.8 133.3 58.3 18.7 48.2  表3  2021年1—7月份规模以上工业企业主要财务指标(分行业)  行 业 营业收入 营业成本 利润总额 1-7月 同比增长 1-7月 同比增长 1-7月 同比增长 (亿元) (%) (亿元) (%) (亿元) (%) 总计 694769.5 25.6 581062.0 24.4 49239.5 57.3  煤炭开采和洗选业 14518.8 32.7 9443.9 20.1 2584.4 127.9  石油和天然气开采业 4943.4 31.2 3000.3 8.1 1168.3 266.7  黑色金属矿采选业 3401.2 55.4 2431.8 39.9 563.4 189.8  有色金属矿采选业 1651.0 18.8 1142.5 12.4 284.6 79.2  非金属矿采选业 2163.9 16.7 1623.0 15.7 206.1 24.0  开采专业及辅助性活动 1017.9 -1.3 968.9 -2.5 3.9 (注1)  其他采矿业 7.2 38.5 6.0 46.3 0.3 0.0  农副食品加工业 29629.4 17.4 27118.8 18.4 970.2 0.7  食品制造业 11513.0 11.5 9057.1 13.0 883.5 4.4  酒、饮料和精制茶制造业 9537.9 16.5 6261.7 14.4 1624.1 27.3  烟草制品业 7921.8 7.3 2330.0 3.2 1119.9 9.5  纺织业 13847.2 15.9 12293.7 16.5 545.6 4.2  纺织服装、服饰业 7799.4 11.0 6693.5 10.9 332.3 9.8  皮革、毛皮、羽毛及其制品和制鞋业 5997.9 11.1 5203.7 11.1 288.1 -1.4  木材加工和木、竹、藤、棕、草制品业 5138.0 17.9 4635.5 18.1 181.9 13.1  家具制造业 4302.6 25.2 3600.7 25.2 223.3 31.0  造纸和纸制品业 8280.5 22.0 7057.4 21.0 529.7 58.6  印刷和记录媒介复制业 3949.0 17.0 3337.9 17.5 207.1 6.4  文教、工美、体育和娱乐用品制造业 7659.0 23.6 6662.5 23.9 342.4 23.3  石油、煤炭及其他燃料加工业 30591.1 33.0 24554.0 25.0 2085.7 (注2)  化学原料和化学制品制造业 45005.2 34.6 36695.1 29.9 4544.9 162.4  医药制造业 16436.1 27.4 8637.3 16.1 3585.8 91.9  化学纤维制造业 5688.9 36.6 5014.7 30.2 382.4 384.7  橡胶和塑料制品业 15871.8 22.0 13373.1 22.6 948.0 16.3  非金属矿物制品业 35373.2 20.9 29369.0 21.0 2791.4 21.0  黑色金属冶炼和压延加工业 55642.7 46.0 50642.3 42.5 2964.7 181.6  有色金属冶炼和压延加工业 38131.1 36.7 35093.7 33.4 1641.3 200.1  金属制品业 25308.1 31.7 22315.8 31.6 1086.7 43.9  通用设备制造业 25963.2 25.2 21386.1 25.5 1767.4 25.7  专用设备制造业 20078.5 20.9 15974.2 21.9 1577.9 17.7  汽车制造业 49069.9 20.7 41978.2 21.7 3221.1 19.7  铁路、船舶、航空航天和其他运输设备制造业 6710.1 18.3 5738.9 18.9 322.9 10.3  电气机械和器材制造业 44566.0 32.9 38131.0 34.2 2350.1 30.2  计算机、通信和其他电子设备制造业 74120.3 19.3 63763.0 17.5 4138.6 43.2  仪器仪表制造业 4708.2 23.3 3541.8 23.3 472.0 20.4  其他制造业 1078.8 21.7 908.8 21.9 55.6 15.1  废弃资源综合利用业 4666.9 70.2 4406.4 72.5 153.4 54.5  金属制品、机械和设备修理业 750.2 1.2 627.3 -1.6 36.4 17.4  电力、热力生产和供应业 43310.7 16.8 39050.9 19.1 2277.2 -2.8  燃气生产和供应业 6296.5 27.0 5450.3 27.1 535.9 43.6  水的生产和供应业 2123.0 19.5 1541.0 18.7 240.6 32.5 注: 1. 开采专业及辅助性活动上年同期亏损4.9亿元。 2. 石油、煤炭及其他燃料加工业上年同期亏损68.5亿元。 3. 本表部分指标存在总计不等于分项之和情况,是数据四舍五入所致,未作机械调整。    附注:   一、指标解释及相关说明   1、利润总额:指企业在生产经营过程中各种收入扣除各种耗费后的盈余,反映企业在报告期内实现的盈亏总额。   2、营业收入:指企业从事销售商品、提供劳务和让渡资产使用权等生产经营活动形成的经济利益流入。包括主营业务收入和其他业务收入。   3、营业成本:指企业从事销售商品、提供劳务和让渡资产使用权等生产经营活动发生的实际成本。包括主营业务成本和其他业务成本。营业成本应当与营业收入进行配比。   4、资产总计:指企业过去的交易或者事项形成的、由企业拥有或者控制的、预期会给企业带来经济利益的资源。   5、负债合计:指企业过去的交易或者事项形成的、预期会导致经济利益流出企业的现时义务。   6、所有者权益合计:指企业资产扣除负债后由所有者享有的剩余权益。   7、应收账款:指资产负债表日以摊余成本计量的,企业因销售商品、提供服务等经营活动应收取的款项。   8、产成品存货:指企业报告期末已经加工生产并完成全部生产过程、可以对外销售的制成产品。   9、营业收入利润率=利润总额÷营业收入×100%,单位:%。   10、每百元营业收入中的成本=营业成本÷营业收入×100,单位:元。   11、每百元营业收入中的费用=(销售费用+管理费用+研发费用+财务费用)÷营业收入×100,单位:元。   12、每百元资产实现的营业收入=营业收入÷平均资产÷累计月数×12×100,单位:元。   13、人均营业收入=营业收入÷平均用工人数÷累计月数×12,单位:万元/人。   14、资产负债率=负债合计÷资产总计×100%,单位:%。   15、产成品存货周转天数=360×平均产成品存货÷营业成本×累计月数÷12,单位:天。   16、应收账款平均回收期=360×平均应收账款÷营业收入×累计月数÷12,单位:天。   17、两年平均增速是指以2019年相应同期数为基数,采用几何平均的方法计算的增速。   18、在各表的利润总额同比增长栏中,标“注”的表示上年同期利润总额为负数,即亏损;数值为正数的表明利润同比增长;数值在0至-100%之间(不含0)的表明利润同比下降;下降幅度超过100%的表明由上年同期盈利转为本期亏损;数值为0的表明利润同比持平。   二、规模以上工业企业利润总额、营业收入等指标的增速均按可比口径计算。报告期数据与上年所公布的同指标数据之间有不可比因素,不能直接相比计算增速。其主要原因是:(一)根据统计制度,每年定期对规模以上工业企业调查范围进行调整。每年有部分企业达到规模标准纳入调查范围,也有部分企业因规模变小而退出调查范围,还有新建投产企业、破产、注(吊)销企业等变化。(二)加强统计执法,对统计执法检查中发现的不符合规模以上工业统计要求的企业进行了清理,对相关基数依规进行了修正。(三)加强数据质量管理,剔除跨地区、跨行业重复统计数据。   三、统计范围   规模以上工业企业,即年主营业务收入为2000万元及以上的工业法人单位。   四、调查方法   规模以上工业企业财务状况报表按月进行全面调查(1月份数据免报)。   五、行业分类标准   执行国民经济行业分类标准(GB/T4754-2017),具体请参见http://www.stats.gov.cn/tjsj/tjbz/hyflbz/。 

有大佬在阿里云上搭过 redash 吗

系统版本查看了下是 Centos6, 官方给的 setup 教程是基于 Ubuntu 的,然后社区里面搜了下 Centos 相关的脚本都是 基于 Centos7 的,试着跑了一下也是各种报错,是不是 Centos6 很老了啊? Linux 小白属实给难住了, 有大佬指点一二吗

centos6 大佬 报错 centos10 条回复 • 2021-08-13 13:36:11 +08:00
snuglove 1
snuglove 25 天前
根据官方支持计划,centos6 已于 2020 年 11 月 30 日停止维护.
Vegetable 2
Vegetable 25 天前
https://hub.docker.com/r/redash/redash
defunct9 3
defunct9 24 天前
开 ssh,让我上去装
Vegetable 4
Vegetable 24 天前
没看到 Linux 小白哈

https://redash.io/help/open-source/dev-guide/docker
NathanDo 5
NathanDo 24 天前
@Vegetable 大佬,这个 link 看到过,不过对 docker 也不是很熟,这个是装了 docker,Redis 还有 PostgreSQL 然后下载这个 image 就可以跑了吗?如果想自定义口啥的是不是不能用这种方式
NathanDo 6
NathanDo 24 天前
@snuglove 那看来是挺老的了 ?
NathanDo 7
NathanDo 24 天前
@defunct9 不是我的机器哈哈,别人让我帮忙的 ?
aru 8
aru 24 天前
centos 6 对新手来说编译软件太难了,可以有几个选择
1. 重装系统,至少 centos 7,Debian 10 、Ubuntu 18.04 以上都可以
2. 请人代为编译安装
3. 别装了
NathanDo 9
NathanDo 24 天前
@aru 好的大佬,我选择 3 ?
ngloom 10
ngloom 14 天前
用 docker 装的。。。
redash 9 beta 了一年没个下文,redash 10 beta 来了。

阿里云 OSS Bucket 被墙了怎么搞?

OSS 都能墙也是*次见,昨天好好的,早上有客户报告说图片无法显示,于是

发工单客户回复说:

您好, 由于香港与中国大陆的网络受到网络管制,导致经常性的被墙。这个对公网跨境流量而言,属于不可抗力因素。

%title插图%num

然后想着那没办法走 CDN 试试,结果阿里云自己的 CDN 在大陆也访问不了自家香港 OSS 源站。 客服非让我开通快速传输功能,这玩意儿价格 1.25 元 /G,开了之后有一个快速传输专属的 Endpoint 域名,IP 换了当然可以访问了,但流量确实用不起,源站下行流量再加上快速传输流量,差不多 2 块钱 1G 。

那就用大陆服务器中转一下吧,居然大陆服务器内网都无法访问自家的香港 OSS

阿里云这种明明换个 IP 就能解决的问题,为何要用户自己认倒霉。

跟客服扯皮,解决方案只有新建一个 Bucket 把数据迁移过去,下行流量费自负。另一个方案是开通快速传输给贵价流量费。

OSS 源站 流量费 CDN19 条回复 • 2021-08-20 20:16:54 +08:00
lshero 1
lshero 9 天前
阿里云腾讯云都在 cloudflare 的带宽联盟中
lance6716 2
lance6716 9 天前 via Android
缺钱了
shuimugan 3
shuimugan 9 天前 ❤️ 1
这种无非就是套娃,一层一层套.

比如利用 Cloudflare 可以反代被墙的 ip,那么也可以用来反代被墙的 bucket.

如果是私有的 bucket 需要计算签名的话,之前不知道哪里看到 Cloudflare 好像还能计算好那些对象存储的签名,但我没考证过.

也可以自己写个自动计算签名的 proxy,我之前用 nodejs 写过一个,200 来行代码搞定,然后部署到香港服务器比如轻量云上,保险起见还能再套一层 Cloudflare
locoz 4
locoz 9 天前 via Android
阿里云好像有个私有专线,在弹性公网 IP 那个里面可以选择加速服务,跨境流量可以直接走阿里云专线直通,不知道会不会过墙…
kingfalse 5
kingfalse 9 天前 via Android
就是养肥了该宰了,没有别的意思
eason1874 6
eason1874 9 天前 ❤️ 1
在同地域开一台便宜竞价机器,内网下载到机器硬盘流量免费,再从机器上传到任意地域 OSS 流量也免费,只需要付 OSS 请求费和临时机器费用
a719031256 7
a719031256 9 天前
鉴定:楼主肥羊一只
xingyuc 8
xingyuc 9 天前 ❤️ 15
对内,他们称香港是境外;
对外,他们坚持一个中国。
cubecube 9
cubecube 9 天前
这个和宰客没关系吧,楼上的也太恶意推测了。
wall 的行为不可预判而已,哪怕是运营商和云服务商也没办法呀。
smileawei 10
smileawei 9 天前
OSS 有个功能是全球加速。按流量收费的。你值得拥有。

salmon5 11
salmon5 9 天前
我觉得阿里云没问题,就像你的身份证号,换成北京户口不就是换个号吗,你办个试试?看看是不是这么简单
myqoo 12
myqoo 9 天前
多申请几个域名 /IP 做冗余,然后在客户端自动选择*快的。
butanediol2d 13
butanediol2d 9 天前 via iPhone
@xingyuc 歪个楼?
《中华人民共和国出入境管理法》第八章,第八十九条:

入境,是指由其他国家或者地区进入中国内地,由香港特别行政区、澳门特别行政区进入中国内地,由台湾地区进入中国大陆。

可见香港确实是境外。
LGA1150 14
LGA1150 8 天前 via Android
@salmon5 然而迁户口并不会变身份证号
stimw 15
stimw 8 天前
@lshero #1 阿里不知道,腾讯是需要国际站用户才能用带宽联盟的。
lshero 16
lshero 8 天前
@stimw https://www.aliyun.com/product/news/detail?spm=5176.20947395.xingqu.1.6bbd2857lLqc4u&id=17749
好像可用区是境外的就行了

@eason1874 直接用 oss 自带的工具迁移就行了,机器都不用开 https://help.aliyun.com/document_detail/95074.html
stimw 17
stimw 8 天前
@lshero #15 他这个产品文档给的网址进去就是国际站…估计就是国际站没跑了,腾讯阿里对带宽联盟是一个尿性
xingyuc 18
xingyuc 7 天前
@butanediol2d 其他国家我不清楚,但是我想有一天去自己国家也不用办各种证件……虽然也不一定会去看
ByteCat 19
ByteCat 6 天前 via iPhone
我今天也遇到这个问题了,电信无法访问,但移动联通正常,dns 解析的 IP 是 47.57.197.41

如何快速部署一个Elasticsearch集群?

Elasticsearch概述

Elasticsearch是一款非常强大的开源“搜索”及“分析”引擎。除了搜索,结合Kibana、Logstash、Beats,以及Elastic Stack的技术生态,Elasticsearch还被广泛运用在大数据实时分析领域——包括日志分析(ELK)、指标监控、信息安全等领域。

Elasticsearch起源于开源搜索引擎类库Lucene,Elasticsearch的创始人Shay Banon于2004年基于Lucene开发了“Compass”,并在2010年重写“Compass”项目之后,将其正式命名为“Elasticsearch”。

目前在搜索引擎分类排名中Elasticsearch名列*,除此之外,同类的产品还有Solor(Apache开源项目)和Splunk(商业项目),它们三者提供的功能非常相似。但是在程序员开源社区中Elasticsearch的活跃度*高。

Elasticsearch的功能特性

Elasticsearchs是一种典型的分布式系统,支持水平扩展。当数据规模变大的时候,Elasticsearch的集群节点可以从单个扩展到数百个。

Elasticsearch集群还支持设置不同的节点类型。例如针对日志类的应用可以支持Hot&Warm架构——冷热架构部署。Elasticsearch的分布式架构如下图所示:

%title插图%num

除此之外,Elasticsearch还支持多种方式集成接入。例如,可以被多种语言方便的集成(Java、.Net、Python、PHP..);灵活的RESTful API;*新版本甚至还支持JDBC&ODBC方式的接入。

Elastic Stack家族成员

Elasticsearch之所以如此流行,处理活跃的社区外,很重要的一点就在于其背后还有一个强大的商业公司——Elastic在支撑。Elastic Stack的生态圈,如下图所示:

%title插图%num

接下来分别介绍下Elastic Stack各技术组件的用途,具体如下:

Logstash

开源的服务器端数据处理管道,支持从不同来源采集数据,转换数据,并将数据发送到不同的存储库中。2013年被Elasticsearch收购。

Logstash支持实时解析和转换数据,例如,从IP地址破译出地理坐标,以及将PII数据匿名化,完全排除敏感字段等。此外,Logstash还支持插件的扩展方式,目前大约有200多个插件,可以解决日志、数据库等多种场景的实际需求。

另外,Logstash的可靠性及安全性也很高。Logstash会通过持久化队列来保证至少将运行中的事件送达一次,以及支持数据传输加密。

Kibana

基于Logstash的数据可视化分析工具。

Beats

轻量的数据采集器,Go语言开发,运行速度非常快。场景的Beats插件有:Filebeat(日志文件插件)、Packetbeat、Heartbeat等。

X-Pack(商业化套件-已开源)

X-Pack开源之后,部分X-Pack功能支持免费使用,例如6.8和7.1版本开始,Security功能可以免费使用。

Elastic Stack应用场景

Elastic Stack技术栈常见的应用场景如下:

(1)下载Kibana安装包,命令如下:

  1. $ wget https://artifacts.elastic.co/downloads/kibana/kibana-7.14.0-darwin-x86_64.tar.gz

下载*新的7.14.0版本的MacOS二进制安装包。之后解压下载的安装包,命令如下:

  1. $ tar zxvf kibana-7.14.0-darwin-x86_64.tar.gz

(2)编辑conf/kibana.yaml文件,指定elasticsearch集群实例的地址编辑配置文件,指定Elasticsearch的集群地址,修改的内容如下:

  1. # The URLs of the Elasticsearch instances to use for all your queries.
  2. elasticsearch.hosts: [“http://localhost:9204”,“http://localhost:9201”,“http://localhost:9203”]

(3)启动Kibana,命令如下:

  1. $ ./bin/kibana

此时,打开浏览器进入Kibana的首页,如下图所示:

%title插图%num

如上图所示,可以向Elasticsearch集群中添加Kibana提供的样例数据。

(4)使用Kibana的“Dev Tools”工具Kibana的“Dev Tools”工具,能够帮助我们很方便执行一些elasticsearch的API。如下图所示:

%title插图%num

具体的查询命令如下:

  1. #执行查询集群节点状态的API。
  2. get /_cat/nodes/?v

 

从Hadoop到云原生,谈如何消除程序员35岁危机

 

%title插图%num

 

35岁这个“职场枯荣线”,确实真实存在。

不知从何时起,很多企业将入职门槛限定在35岁以下,“35岁”已然成为职场中年的魔咒。尤其是程序员这个群体,年龄*对是*难以隐忍的痛点。因为很多程序员普遍存在于如前期“打英雄”发育快,越到后期越乏力的尴尬窘境。

提前做好规划,看清技术趋势,不沉迷于以往的成就,不仅可以优雅过渡35岁危机,甚至会迎来职场真正的黄金期。

无论么时候,锤炼和深挖自己的技能都是必不可少的。但是,跟上快速迭代的技术变化,同样不可忽视。比如,很多程序员声称自己是Hadoop专家,此前他们对此的确非常精通,而如今在精湛的技能下却不得不感到危机,毕竟Hadoop正面临着淘汰,这就意味着以前是专家以后很可能没饭吃。所以,程序员必须意识到技术是不断前进的,如何掌握技术趋势而不是追求热点才是关键所在。

%title插图%num

让Hadoop面临淘汰的,正是来自云原生的力量

伴随云计算的滚滚浪潮,云原生的概念应运而生,而如此火爆的概念却难以用只言片语解释清楚,因为云原生一直在发展变化之中,解释权不归某个人或组织所有。

CNCF对云原生的定义:云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。

我们以CNCF官方的定义来看,云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。云原生技术可以让系统松耦合,支持弹性伸缩、可管理且清晰。通过整合健壮且有效的自动化,工程师可以用很少的劳动来完成频繁的、预期中的高危代码修改。

说白了,如果是Cloud Native的程序,写完之后在云上一发布,程序就自动运行和运维了,我只需要负责业务逻辑就可以了。通俗来说其特征是:

  • 发布的时候*简化,不用指定主机、端口、存储……
  • 日志、容错、数据备份、监控都是自动的
  • 底层硬件错误跟程序员没有关系
  • 自动扩容、降容、加机器、换机器都不是程序员的事情
  • 别人发布应用肯定不会影响自己的应用
  • 如果这家云厂商太贵了,可以直接迁到另一家云上运行
  • 只为自己实际使用的计算和存储付费,不用预先购买

实际上,近两年云计算概念被清晰细分,“云原生”已经成为那条*大的鱼。“大鱼”来了,程序员们能做的不应该是墨守成规,而是必须拥抱“大鱼”。

Hadoop使命已经完成 并一定会被取代

Elephant in the room,比喻一个问题因太过于庞大或麻烦,导致没有人愿意去碰。

巧的是,Hadoop的标志就是一头大象,正面临着“Elephant in the room”这样的窘境。

%title插图%num

不得不说,很多大数据系统不是云原生的,像Hadoop、Hive、Mongo等*大部分大数据组件发展于云计算技术成熟之前,所以这些组件必须自己做协同、存储、备份、日志,来处理资源与集群管理。

而像Kubernetes这样的云基础设施,很长一段时间对Stateful Applications(有状态应用)的支持并不友好。即使像Spark这样在云原生的环境下开发的应用(其原生就是在Mesos集群中发布),并没有做自己调度和集成管理,但是后期为了与K8s兼容,还是做了很多改动,今年年初才进入GA的阶段。

但是,随着Kubernetes对各种大数据组件的支持不断完善,Hadoop的历史使命似乎已经逐渐完成,而所有的新的大数据应用,大概率都会基于容器发布,否则必将失去市场。

Hadoop如何被取代?

Hadoop的三驾马车是MapReduce、YARN、HDFS。

%title插图%num

其中,MapReduce因效率太低,早已被Spark所取代;YARN并非正规的容器且效率不高,可以被类似于K8s的新一代容器调度体系取代;唯一生命力比较强的是HDFS,因为大部分大数据组件的HDFS API是兼容的,所以取代HDFS暂时有些难度。

尽管,HDFS很难被去掉,不过不用担心,因为基本上HDFS只有API是真正有用的。

因为很多程序是用HDFS的API使用的,如图通过HDFS连接器,再通过TCP访问HDFS,效率是*高的。当然也可以通过S3A、WASBS、O3FS访问相应的S3、MinIO、Ozone……但如果意识到HDFS是真正的存储,下面都是其他的存储,只需要使用相同的API就可以了。

%title插图%num

所以,其实Hadoop里所有的东西都可以替换。如图,显示了在不安装Hadoop的情况下,可以相对应替代的工具。

%title插图%num

图片来源:Cloud Native Data Platform without Hadoop Installation

以前,传统Hadoop的方式,在Lambda架构中所有的应用都在各自的主机上运行。

%title插图%num

图片来源:Big Data without Hadoop/HDFS? MinIO tested on Jupyter + PySpark

现在,可以把所有的数据处理放在云上。

%title插图%num

甚至可以把整个存储放在Kubernetes上。

%title插图%num

综上所述,我们看到,Hadoop的去除,使得应用在容器化中运行,能够让管理更加方便,从而大大减少工作的复杂度,全面的让大数据平台,享受云原生的好处,因此,这必定是未来的趋势。

当然,并不是只有我们意识到了Hadoop如今尴尬的问题,像这样的说法其实已经得到了初步的共识,诸如像《云原生数据平台,无需安装Hadoop》《没有Hadoop/HDFS的大数据,怎么样用Jupyter+PySpark来做MinIO测试》《构建云原生,在各个云上都可以迁移的数据湖》这样的文章,都能够窥见“去Hadoop”的趋势。

其中一篇名为《没有Hadoop的大数据》的文章,介绍“用户已经在公有云上为特定地区建立了一个完整的数据湖和分析解决方案,并希望将这个解决方案部署到另一个区,而此前的数据湖并不是云原生的,所以负责解决方案的部门通过一系列操作(如图),实现了云原生架构,才得以在不同的公有云上顺利实现该解决方案。”

%title插图%num

云原生的组件

原文链接:

https://towardsdatascience.com/building-a-cloud-native-cloud-agnostic-data-lake-376aa2f2aacd

云原生新思考 它为什么越来越重要?

首先,我们来看一下CNCF发布的云原生全景图,这张全景图技术之多规模之大,无疑会让人感到震惊。可见,云原生发展之迅猛,可提供的服务与选择非常多。

%title插图%num

云原生技术图谱

关于这份云原生技术图谱,详细内容可以参考我们之前发布的文章《都在说云原生,它的技术图谱你真的了解吗?》。

显然,现在构建一个系统比云原生之前的时代容易多了。如果构建恰当,云原生技术将提供更强大的灵活性。在现如今快速变化的技术生态中,这可能是*重要的能力之一。

接下来,我们要讲的重点是云原生的要点之一DevOps,作为是一个合成词,DevOps由开发(Developments)和运维(Operations)两个单词组成,其主要目的是拆断不同部门之间隔离的墙。简而言之,DevOps可以让公司的流程更快、更有效,并且更可靠。

那么,DevOps的平台功能,是作为容器调度平台完全基于编排和部署,并且能够将云原生应用的生命周期进行抽象,可以替换存储、CRI等,甚至发布流程都可以用不同的策略来管理;以代码形式部署集群;开放接口CRI、CNI、CSI的插件架构。

这就是DevOps的核心价值,在此基础上还提供了一些常用服务,例如:负载均衡、存储编排、自动部署和回滚、混排、容错、机密和配置管理……

K8s将整个分布式集群的发布变成云原生,发布到一个分布式集群,用K8s一整套的YAML描述出来就可以在一个集群上发布,也可以在另一个集群上发布。

DataOps与DevOps十分形似,也有着与DevOps类似的软件开发角色,它是数据工程师简化数据使用、实现以数据驱动企业的方法,也是企业顺利实现第三阶段的关键。

那么,我们的思考是DataOps是否也可以这样做?

将DevOps变量替换到DataOps,我们看DataOps的核心价值主要是基于容器的部署和编排、生命周期的抽象、DSL——作为代码的管理部署、支持不同分析工作负载的插件架构。以及常用服务调度、元数据、数据质量、访问控制、版本控制、自动部署和回滚、日志/审计……

简而言之,DataOps遵循类似于 DevOps 的方法:从编写代码到生产部署的路径(包括调度和监控)应由同一个人完成,并遵循系统管理的标准。与提供许多标准 CI、部署、监控工具以实现快速交付的 DevOps 类似,通过标准化大量大数据组件,新手可以快速建立生产级的大数据应用并充分利用数据的价值。(关于DataOps的详细内容,可以参考我们之前发布的文章《一文读懂DataOps》。)

从Hadoop的气数已尽到云原生的风光正好,看起来是说新技术的快速迭代,但实际上对于Hadoop这样的分布式系统的深入理解其实也是精通云原生架构大数据体系的基础。总之,我们要避免的是固守就有技术,以为“一招鲜吃遍天”,而是要从架构、体系上,充分理解自己的工作内容,并不断巩固算法、架构、测试、工程管理与沟通等基础知识技能体系。

*重要的是,要时刻保持学习和提高的心态。如果这样,程序员完全不会存在35岁危机,而会在这个黄金年龄迎来自己的收入巅峰。如今,云原生与数字化的转型大潮才刚刚开始,我们希望所有的程序员都能够抓住机会,深耕专业技术能力实现人生价值。

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速