首页 文章 精选 留言 我的

精选列表

搜索[设计协作平台],共10000篇文章
优秀的个人博客,低调大师

高可用服务架构设计(12) - 基于request cache请求缓存技术优化批量商品数据查询接口

0 Github 回顾执行流程 1、创建command,2种command类型 2、执行command,4种执行方式 3、查找是否开启了request cache,是否有请求缓存,如果有缓存,直接取用缓存,返回结果 首先,reqeust context(请求上下文) 一般在一个web应用中,Hystrix会在一个filter里面,对每个请求都添加一个请求上下文 即Tomcat容器内,每一次请求,就是一次请求上下文 然后在这次请求上下文中,我们会去执行N多代码,调用N多依赖服务,有的依赖服务可能还会调用好几次 在一次请求上下文中,如果有多个command,参数及调用的接口也是一样的,其实结果也可以认为是一样的 那么就可以让第一次command执行返回的结果缓存在内存,然后这个请求上下文中,后续的其他对这个依赖的调用全部从内存中取用缓存结果即可 这样避免在

优秀的个人博客,低调大师

深度| 一篇文章为你解读SOFA-DTX 分布式事务的设计演进路线

小蚂蚁说: 本文介绍了蚂蚁金服在分布式事务上,经过多年发展,服务于内外部大量不同业务,沉淀出的一整套包含TCC、FMT、XA模型的分布式事务解决方案。并且在持续对外输出的过程中,进一步打磨产品体验,适应各种严苛的金融级场景和机构需求,比如跨机房跨地域的容灾业务连续性保障能力等。 移除 点击此处添加图片说明文字 随着互联网技术快速发展,数据规模增大,采用分布式数据库或者跨多个数据库的分布式微服务应用在中大规模企业普遍存在,而由于网络、机器等不可靠因素,数据一致性的问题很容易出现,与可扩展性、高可用容灾等要求并肩成为金融IT架构支撑业务转型升级的最大挑战之一。 在蚂蚁金服核心系统提出微服务化时,曾遇到了非常大的技术难题。首先是在服务拆分以后,面临跨服务的一致性问题;其次,支付宝当时的峰值交易量已经非常高了,在解决一致性问题的同时,还需要兼顾性

优秀的个人博客,低调大师

Android 框架设计Demo,一个简单的MVP示例搜索功能,网络请求用Retrofit+RxJava实现

项目的业务逻辑不断变更,需求也不断扩张,导致在原有代码基础上去处理也变得越来越繁琐,这时项目框架和代码规范就显得非常必要了。Google 在 GitHub 上的 Android Architecture Blueprints 提供了很多框架 Demo,现在对其中的 todo‑mvp 做一个简单的分析,并模仿写一个简单的 Demo。 一、MVP 基本结构 MVP 从更早的 MVC 框架演变过来,与 MVC 有一定的相似性:Controller/Presenter 负责逻辑的处理,Model 提供数据,View 负责显示。在 Android 上可以大大减轻 Activity 的负担,同时增加扩展性和耦合度。 View:负责绘制 UI 元素、与用户进行交互(在 Android 中体现为 Activity)Model:负责存储、检索、操纵数据(有时也实现一个 Model interface 用来降低耦合)Presenter:作为 View 与 Model 交互的中间纽带,处理与用户交互的负责逻辑二、TodoMVP 框架结构 有如下几个步骤: 在 Activity 中初始化 Fragment 和 Presenter 的实例,并给 Fragment 设置 PresenterFragment 实现了 View 的接口,并拥有 Presenter 的引用,Fragment 的非 UI 操作都通过调用 Presenter 来实现,同时 Presenter 把处理好的结果通过回调 View 回传给 Fragment 显示Presenter 拥有 View 的引用,具体的处理事情并回调 View 返回接口正因为 UI 与具体实现相分离,使 Activity 只需要根据回传状态渲染 UI,Presenter 中也只用考虑处理逻辑,将处理好的状态告知 View 即可。在应用 UI 经常变更时会有非常大的优势。 三、参照写一个简单的 Demo 写一个简单的搜索 Demo,输入关键字,在点击搜索按钮时开始搜索,并将返回结果显示出来。 SearchContract 的实现,View 中包含搜索成功和搜索失败的回调,Presenter 中主要是搜索方法和 Activity 生命周期的方法。 public interface SearchContract { interface View extends BaseView<SearchContract.Presenter> { void onSearchSuccess(String result); void onSearchFailure(String message); } interface Presenter extends BasePresenter { void stop(); void startSearch(String searchKey); } } 在 MainActivity 中实现了 SearchContract.View,并创建 SearchPresenter 实例和初始化 UI。 public class MainActivity extends AppCompatActivity implements SearchContract.View { private SearchContract.Presenter mPresenter; private EditText etSearchKey; private TextView tvResult; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new SearchPresenter(this, new DataManager()); etSearchKey = (EditText) findViewById(R.id.et_search_key); tvResult = (TextView) findViewById(R.id.tv_result); findViewById(R.id.btn_search).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String searchKey = etSearchKey.getText().toString(); if (TextUtils.isEmpty(searchKey)) { showToast("搜索关键字不能为空!"); return; } mPresenter.startSearch(searchKey); } }); } @Override public void onResume() { super.onResume(); mPresenter.start(); } @Override protected void onStop() { super.onStop(); mPresenter.stop(); } @Override public void onSearchSuccess(String result) { tvResult.setText(result); } @Override public void onSearchFailure(String message) { tvResult.setText(message); } @Override public void setPresenter(SearchContract.Presenter presenter) { mPresenter = presenter; } public void showToast(String message) { Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); } } 创建 SearchPresenter 实现 SearchContract.Presenter 接口,其中的搜索方法通过调用 Model 层的接口获取数据,并处理完结果后将状态回调给 View。 public class SearchPresenter implements SearchContract.Presenter { private SearchContract.View searchView; private CompositeSubscription mCompositeSubscription; private DataManager dataManager; private String mResult; public SearchPresenter(SearchContract.View searchView, DataManager dataManager) { this.searchView = searchView; this.dataManager = dataManager; this.searchView.setPresenter(this); } @Override public void start() { mCompositeSubscription = new CompositeSubscription(); } @Override public void stop() { if (mCompositeSubscription.hasSubscriptions()) { mCompositeSubscription.unsubscribe(); } } @Override public void startSearch(String searchKey) { mCompositeSubscription.add(dataManager.getSearchResult(searchKey) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<ResponseBody>() { @Override public void onCompleted() { if (mResult != null) { searchView.onSearchSuccess(mResult); } } @Override public void onError(Throwable e) { e.printStackTrace(); searchView.onSearchFailure("请求失败!!!"); } @Override public void onNext(ResponseBody responseBody) { if (responseBody != null) { try { mResult = responseBody.source().readUtf8(); } catch (IOException e) { e.printStackTrace(); } } } }) ); } } 原文博客地址:http://www.apkbus.com/blog-928212-77226.html

优秀的个人博客,低调大师

【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面

大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了,要想实现应用程序只启动一次引导界面这样的效果,只要使用SharedPreferences类,就会让程序变的非常简单,下面来详细介绍一下这个类的使用方法 1.SharedPreferences的详细介绍和用法 其实在20.游戏开发基础(游戏数据存储)中已经有过介绍了,为了文章的完整还是再介绍一遍。 做软件开发应该都知道,很多软件会有配置文件,里面存放这程序运行当中的各个属性值,由于其配置信息并不多,如果采用数据库来存放并不划算,因为数据库连接跟操作等耗时大大影响了程序的效率,因此我们使用键值这种一一对应的关系来存放这些配置信息。SharedPreferences正是Android中用于实现这中存储方式的技术。 SharedPreferences的使用非常简单,能够轻松的存放数据和读取数据。SharedPreferences只能保存简单类型的数据,例如,String、int等。一般会将复杂类型的数据转换成Base64编码,然后将转换后的数据以字符串的形式保存在 XML文件中,再用SharedPreferences保存。 SharedPreferences使用方法: <1> 使用Activity类的getSharedPreferences方法获得SharedPreferences对象,其中存储key-value的文件的名称由getSharedPreferences方法的第一个参数指定; <2> 使用SharedPreferences接口的edit获得SharedPreferences.Editor对象; <3> 通过SharedPreferences.Editor接口的putXxx方法保存key-value对。其中Xxx表示不同的数据类型。例如:字符串类型的value需要用putString方法; <4> 通过SharedPreferences.Editor接口的commit方法保存key-value对。commit方法相当于数据库事务中的提交(commit)操作。 具体代码的书写流程为: A、存放数据信息 <1> 打开Preferences,名称为setting,如果存在则打开它,否则创建新的Preferences SharedPreferences settings = getSharedPreferences(“setting”, 0); <2> 让setting处于编辑状态 SharedPreferences.Editor editor = settings.edit(); <3> 存放数据 editor.putString(“name”,”cnblogs”); editor.putString(“URL”,”www.cnblogs.com”); <4> 完成提交 editor.commit(); B、读取数据信息 <1> 获取Preferences SharedPreferences settings = getSharedPreferences(“setting”, 0); <2> 取出数据 String name = settings.getString(“name”,”默认值”); String url = setting.getString(“URL”,”default”); 以上就是SharedPreferences的使用方法,其中创建的Preferences文件存放位置可以在Eclipse中查看: DDMS->File Explorer /data/data/<package name>/shared_prefs/setting.xml 2.实现的效果图(图片分别为欢迎界面、引导界、软件主页) 第一次启动程序:欢迎界面-->引导界面-->软件主页 以后启动程序:欢迎界面-->软件主页 3.具体的实现编码 (1)欢迎页面Java代码,就是简单的建个线程,延迟指定时间,然后跳转就可以了 WelcomeActivity (2)引导页面,用的ViewPager实现的,可以参考下ViewPager介绍和简单实现,具体可以在源代码中查看 (3)主页,这就没什么好说的了,就一个显示布局的页面。 本文转自叶超Luka博客园博客,原文链接:http://www.cnblogs.com/yc-755909659/p/4284100.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

【Android UI设计与开发】7.底部菜单栏(四)PopupWindow 实现显示仿腾讯新闻底部弹出菜单

前一篇文章中有用到 PopupWindow 来实现弹窗的功能。简单介绍以下吧。 官方文档是这样解释的:这就是一个弹出窗口,可以用来显示一个任意视图。出现的弹出窗口是一个浮动容器的当前活动。 1.首先来个简单的栗子,效果如下: 只有两个布局文件,一个是弹窗布局(只有一张图片),一个是主界面布局(只有一个按钮)。 然后在主界面代码中实例PopupWindow ,指定弹出的界面,在按钮点击事件中显示或隐藏弹窗就可以了,代码如下: package com.yanis.demo; import android.app.Activity; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout.LayoutParams; import android.widget.PopupWindow; public class PopupWindowActivity extends Activity { PopupWindow pop; Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_popup_window); btn = (Button) findViewById(R.id.btnShowWindow); LayoutInflater inflater = LayoutInflater.from(this); // 引入窗口配置文件 - 即弹窗的界面 View view = inflater.inflate(R.layout.my_popup_window, null); // PopupWindow实例化 pop = new PopupWindow(view, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, false); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (pop.isShowing()) { // 隐藏窗口,如果设置了点击窗口外消失,则不需要此方式隐藏 pop.dismiss(); } else { // 弹出窗口显示内容视图,默认以锚定视图的左下角为起点,这里为点击按钮 pop.showAsDropDown(v); } } }); } } 2.知道了怎么实现 PopupWindow 弹窗,利用其特性替换系统自带的菜单栏,来个仿腾讯新闻的菜单吧,效果图如下: 布局什么的花点时间,慢慢调,自然就出来了,主要还是主界面的逻辑代码啊,菜单就是通过 PopupWindow 来显示的,具体代码如下: package com.yanis.popup_window; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.util.Log; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnKeyListener; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout.LayoutParams; import android.widget.PopupWindow; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener, OnKeyListener { PopupWindow pop; TextView hideView; Button btnCancel; ImageView btnNight, btnWord, btnExit; View view; boolean isOut, isIn;// 是否弹窗显示 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); } /** * 初始化组件 */ private void initView() { hideView = (TextView) findViewById(R.id.hideView); LayoutInflater inflater = LayoutInflater.from(this); // 引入窗口配置文件 - 即弹窗的界面 view = inflater.inflate(R.layout.menu_view, null); btnNight = (ImageView) view.findViewById(R.id.btnNight); btnWord = (ImageView) view.findViewById(R.id.btnWord); btnExit = (ImageView) view.findViewById(R.id.btnExit); btnCancel = (Button) view.findViewById(R.id.btnCancel); } /** * 初始化数据 */ private void initData() { btnNight.setOnClickListener(this); btnWord.setOnClickListener(this); btnExit.setOnClickListener(this); btnCancel.setOnClickListener(this); view.setFocusableInTouchMode(true); view.setOnKeyListener(this); // PopupWindow实例化 pop = new PopupWindow(view, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, true); /** * PopupWindow 设置 */ // pop.setFocusable(true); //设置PopupWindow可获得焦点 // pop.setTouchable(true); //设置PopupWindow可触摸 // pop.setOutsideTouchable(true); // 设置非PopupWindow区域可触摸 // 设置PopupWindow显示和隐藏时的动画 pop.setAnimationStyle(R.style.MenuAnimationFade); /** * 改变背景可拉的弹出窗口。后台可以设置为null。 这句话必须有,否则按返回键popwindow不能消失 或者加入这句话 * ColorDrawable dw = new * ColorDrawable(-00000);pop.setBackgroundDrawable(dw); */ pop.setBackgroundDrawable(new BitmapDrawable()); } /** * 按钮点击事件监听 * * @param v */ @Override public void onClick(View v) { switch (v.getId()) { case R.id.btnNight: changePopupWindowState(); Toast.makeText(MainActivity.this, "你点击了夜间模式", Toast.LENGTH_SHORT) .show(); break; case R.id.btnWord: changePopupWindowState(); Toast.makeText(MainActivity.this, "你点击了文本模式", Toast.LENGTH_SHORT) .show(); break; case R.id.btnExit: exitTheDemo(); break; case R.id.btnCancel: changePopupWindowState(); break; } } /** * 退出程序 */ private void exitTheDemo() { changePopupWindowState(); new AlertDialog.Builder(MainActivity.this).setMessage("确定退出这个 Demo 吗?") .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }).setNegativeButton("取消", null).show(); } /** * 改变 PopupWindow 的显示和隐藏 */ private void changePopupWindowState() { if (pop.isShowing()) { // 隐藏窗口,如果设置了点击窗口外消失,则不需要此方式隐藏 pop.dismiss(); } else { // 弹出窗口显示内容视图,默认以锚定视图的左下角为起点,这里为点击按钮 pop.showAtLocation(hideView, Gravity.BOTTOM, 0, 0); } } // Called when a key was pressed down and not handled by any of the views // inside of the activity @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_MENU:// 菜单键监听 isOut = true; changePopupWindowState(); break; } return super.onKeyDown(keyCode, event); } // Called when a hardware key is dispatched to a view. @Override public boolean onKey(View v, int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_MENU: if (isOut && !isIn) { isOut = false; isIn = true; } else if (!isOut && isIn) { isIn = false; changePopupWindowState(); } break; } return false; } } 本文转自叶超Luka博客园博客,原文链接:http://www.cnblogs.com/yc-755909659/p/4288864.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

长小牛 × 腾讯Kuikly:金融类AI APP三端跨平台架构落地实践

随着证券行业数字化转型与AI技术加速演进,正在重塑财富管理服务模式,针对传统券商App服务被动、触达低效、内容同质化等问题,近年来,长江证券以AI原生架构重构移动证券服务,在行业内第三家推出了原生AI App“长小牛”,覆盖盘前、盘中、盘后及日常场景,推动专业投资服务普惠化。项目以“智能猜你想问”为统一入口,根据客户浏览的资讯、行情、自选和持仓内容生成场景化问题,并通过AI半屏交互嵌入行情、交易、资讯,热点复盘等页面。服务覆盖行情解读、专业研究、持仓分析、交易辅助和个性化跟踪,形成“问题发现—分析解读—服务承接—订阅跟踪—人工服务”的完整链路,为券商AI App建设提供了可复制、可推广的实践路径。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册